假设
b = ["good ", "bad "]
a = ["apple","mango"]
then output = ["good apple","good mango","bad apple","bad mango"]
我知道这可以用嵌套的for循环来完成,但是有一些优雅的衬里使用C ++ STL吗?
假设
b = ["good ", "bad "]
a = ["apple","mango"]
then output = ["good apple","good mango","bad apple","bad mango"]
我知道这可以用嵌套的for循环来完成,但是有一些优雅的衬里使用C ++ STL吗?
这是一个单行(复制自 Jonathan Mee 回答 发布在这里):
for(size_t i = 0, s = a.size(); i < output.size(); ++i) output[i] = b[i/s] + ' ' + a[i%s];
完整的例子 这里。
没有直接的解决方案;我检查了整个 <algorithm>
。这些函数都不产生长度为M * N的输出。
你是什么 能够 做就是打电话 std::for_each
在第一个范围,使用lambda调用 std::for_each
在第二个范围(!)
std::vector<std::string> a, b;
std::for_each(a.begin(), a.end(),
[&](std::string A) { std::for_each(b.begin(), b.end(),
[A](std::string B) { std::cout << A << '/' << B << '\n'; }
);});
但这只是STL中的嵌套循环。
特定 vector<string> a
和 vector<string> b
您可以使用 for_each
:
vector<string> output(size(a) * size(b));
for_each(begin(output), end(output), [&, it = 0U](auto& i) mutable {
i = a[it / size(b)] + ' ' + b[it % size(b)];
++it;
});
编辑:
我们已经初始化了 output
有足够的空间来容纳每一个组合 a
和 b
。然后我们将逐步完成每个元素 output
并分配它。
我们想要使用1ST 的元素 a
为了第一 size(b)
要点 output
,和2ND 的元素 a
第二个 size(b)
元素,等等。所以我们通过索引来做到这一点 it / size(b)
。我们希望通过迭代结合它 b
的元素。
it
将移动到每个元素的下一个索引 output
但索引需要换行,否则它将超出界限 it == size(b)
,为此我们使用 it % size(b)
。
EDIT2:
在 这个问题 通过基准测试我发现了模数和除法是迭代的昂贵操作的现象。我在这里做了同样的测试。为了隔离算法,我只是在a上进行笛卡尔求和 vector<int>
不 vector<string>
。
首先,我们可以看到两种算法导致不同的装配。我上面写的算法需要585行汇编。我的解释需要588行 MSalter的代码
vector<string> output(size(testValues1) * size(testValues2));
auto i = begin(output);
std::for_each(cbegin(a), cend(a), [&](const auto& A) { std::for_each(cbegin(b), cend(b), [&](const auto& B) { *i++ = A + ' ' + B; }); });
我在这里做了一个非常可靠的基准测试: http://ideone.com/1YpzIO 在测试中我只设置了100次测试,但MSalters的算法总是获胜。本地使用Visual Studio 2015,发布时有10,000,000次测试,MSalters算法在我需要的时间内完成约2/3。
显然,模数不是一种很好的索引方法:(