假设
b = ["good ", "bad "]
a = ["apple","mango"]
then output = ["good apple","good mango","bad apple","bad mango"]
我知道这可以通过嵌套for循环来完成,但是使用C ++ STL是否有一些优雅的衬里呢?
答案 0 :(得分:4)
以下是单行(从Jonathan Mee's回复posted here复制):
for(size_t i = 0, s = a.size(); i < output.size(); ++i) output[i] = b[i/s] + ' ' + a[i%s];
完整示例here。
答案 1 :(得分:3)
鉴于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
的每个元素并分配它。
我们要使用a
的1 st 元素作为size(b)
的第一个output
元素,以及2 nd < / sup> a
元素,用于第二个size(b)
元素,依此类推。因此,我们将通过使用it / size(b)
建立索引来实现此目的。我们希望通过b
的元素迭代来组合它。
it
将转移到output
的每个元素的下一个索引,但索引需要换行,或者it == size(b)
时它将超出范围,为此我们使用it % size(b)
1}}。
<强> EDIT2:强>
在this question通过基准测试,我发现了模数和除法是迭代的昂贵操作的现象。我在这里做了同样的测试。为了隔离算法,我只是在vector<int>
而不是vector<string>
上进行笛卡尔求和。
首先我们可以看到两种算法导致不同的装配。我上面写的算法需要585行汇编。我对MSalter's code
的解释需要588行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。
显然,模数不是一种很好的索引方法:(
答案 2 :(得分:3)
没有直接的解决方案;我检查了整个<algorithm>
。这些函数都没有产生长度为M * N的输出。
你可以做的是在第一个范围内调用std::for_each
,使用在第二个范围调用std::for_each
的lambda(!)
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中的嵌套循环。