我有一个函数,它接受一个向量并通过组合其中的所有元素返回一个向量。现在,我有3个嵌套的for循环,它们创建了3级深度的组合。我希望它看起来更好,并且能够根据需要添加功能使其深度达到4级。
如果输入= [“一个”,“两个”,“三个”]
3级输出=“ onetwothree”“ twoonethree”,依此类推。
std::vector<std::string> generator(std::vector<std::string>& x)
{
std::vector<std::string> output;
std::string tmp;
for (auto i : x) {
output.push_back(i);
for (auto j : x) {
tmp = i + j;
output.push_back(tmp);
for (auto k : x) {
tmp = i + j + k;
output.push_back(tmp);
}
}
}
return output;
}
我已经研究了迭代器,但是我不知道它是否可行。
答案 0 :(得分:8)
如果您要查找的是简单地生成字符串向量x
的所有元素的置换并将这些置换存储到另一个输出向量中,则可以使用std::next_permutation和{ {3}}:
#include <vector>
#include <string>
#include <numeric>
#include <iostream>
#include <algorithm>
std::vector<std::string> generator(std::vector<std::string> x)
{
std::vector<std::string> output;
std::sort(x.begin(), x.end());
do
{
output.push_back(std::accumulate(x.begin(), x.end(), std::string()));
} while (std::next_permutation(x.begin(), x.end()));
return output;
}
int main()
{
auto v = generator({"one","two","three"});
for (auto& val : v)
std::cout << val << "\n";
}
默认情况下,std::accumulate
基本上在元素上调用operator +
,因此该字符串将自动连接在一起。
就std::next_permutation
而言,其操作说明在链接中进行了说明。基本上,您想从一个排序的序列开始,然后调用std::next_permutation
以获取元素的下一个排列。
请注意,这与“级别”(如您所称)的数量无关。您可以有一个由10个字符串组成的向量,它可以正常工作(假设没有内存限制)。
答案 1 :(得分:2)
如果要生成最大长度为L的N个单词的所有组合,可以使用以下方法:
std::vector<std::string> generator(const std::vector<std::string> & x, int levels) {
int nWords = x.size();
std::vector<std::string> output;
for (int l = 1; l <= levels; ++l) {
int nCombs = std::pow(nWords, l);
for (int i = 0; i < nCombs; ++i) {
std::string cur;
for (int j = 0, k = i; j < l; ++j) {
cur += x[k%nWords];
k /= nWords;
}
output.push_back(cur);
}
}
return output;
}
仍然有3个嵌套循环,但这适用于L的任何值-不仅限于3。L> N也适用。
答案 2 :(得分:0)
嗨,我曾经在Python中遇到过类似的问题。
我想的目标是创建一个“ n
嵌套”循环,以使n
是一个变量。更好的结果是使级别I_i
的每个索引i
为变量。也就是说,给定列表[I_1,I_2,...,I_n]
,您应该能够生成这样的循环
for i_1 in range( I_1):
for i_2 in range( I_2):
...
for i_n in range(I_n):
some_function(i_1,i_2,...,i_n)
做到这一点的一种方法是使用数学。您可以建立一个数字,使第i
位数字基于I_i
。该数字的最大值仅为I_1*I_2*...*I_n
。这样,整个循环将被折叠成一个简单的循环
for i in range(I_1*I_2*...*I_n):
# obtain these numbers
i_1 = f_1(i)
i_2 = f_2(i)
...
i_n = f_n(i)
some_function(i_1,i_2,...,i_n)
尽管获取i
的功能有些复杂。
另一种实现方法是迭代器。在Python中,它只是import itertools
。但是,在C ++中,我发现了这个cppitertools。我还没有尝试过,但是我想这可以工作。
不过,如果您想提高速度,则首选第一个方法。不过,我认为还有更好的解决方案。