[英]Can I get rid of nested for loops here?
I have a function that takes a vector and returns a vector by combining all the elements in it. 我有一个函数,它接受一个向量,并通过组合其中的所有元素返回一个向量。 Right now, I have 3 nested for loops that create a combination that is 3 levels deep.
现在,我有3个嵌套for循环,创建了3级深度的组合。 I would like it to look better and have the ability to add the functionality to make it 4 levels deep when I want.
我希望它看起来更好,并且能够添加功能,使其在我想要的时候达到4级。
If input = ["one", "two", "three"] 如果输入= [“一个”,“两个”,“三个”]
3 level output = "onetwothree" "twoonethree" and so on. 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;
}
I have looked into iterators, but I can't figure out if it would work. 我已经研究了迭代器,但我无法弄清楚它是否会起作用。
If what you are looking for is to simply generate the permutations of all the elements of the string vector x
and store these permutations into another output vector, this is easily accomplished by using std::next_permutation and std::accumulate : 如果您要查找的是简单地生成字符串向量
x
的所有元素的排列并将这些排列存储到另一个输出向量中,则可以通过使用std :: next_permutation和std :: accumulate轻松完成:
#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";
}
The std::accumulate
basically calls operator +
on the elements by default, thus the string is automatically concatenated. 默认情况下,
std::accumulate
基本上调用元素上的operator +
,因此字符串会自动连接。
As far as std::next_permutation
, the description of what it does is explained at the link. 至于
std::next_permutation
,它在链接中解释了它的作用。 Basically you want to start out with a sorted sequence, and call std::next_permutation
to get the next permutation of elements. 基本上你想从一个排序的序列开始,并调用
std::next_permutation
来获得元素的下一个排列。
Note that this is not contingent of the number of "levels" (as you call it). 请注意,这不取决于“级别”的数量(如您所说)。 You could have a vector of 10 strings, and this would work correctly (assuming there are no memory constraints).
你可以有一个10个字符串的向量,这将正常工作(假设没有内存约束)。
If you want to generate all combinations of N words with max length L you could use this: 如果要生成N个单词的最大长度为L的所有组合,您可以使用:
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;
}
There are still 3 nested loops, but this works for any value of L - not just 3. L > N also works. 仍然有3个嵌套循环,但这适用于L的任何值 - 不仅仅是3. L> N也可以。
Hi I had the similar problem in Python once. 嗨我曾经在Python中遇到过类似的问题。
The goal I suppose is to have a " n
-nested" loops such that n
is a variable. 我想我的目标是有一个“
n
-nested”循环,使得n
是一个变量。 A better result would be to make each index I_i
of level i
be variables. 更好的结果是使级别
i
每个索引I_i
成为变量。 That is to say, given a list [I_1,I_2,...,I_n]
, you should be able to generate such loop 也就是说,给定一个列表
[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)
One way to do this is to use mathematics. 一种方法是使用数学。 You can build a number such that on the
i
th digit, it's I_i
based. 你可以建立一个数字,在第
i
个数字上,它是基于I_i
的。 This number's maxmium value is just I_1*I_2*...*I_n
. 此数字的最大值仅为
I_1*I_2*...*I_n
。 In this way, the entire loop will be collaped into one simple loop 这样,整个循环将被拼接成一个简单的循环
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)
Although the functions to obtain the i
s are a bit complicated. 虽然获得
i
的功能有点复杂。
Another way to do it is, as you have mentioned, iterators. 另一种方法是,正如您所提到的,迭代器。 In Python it's just
import itertools
. 在Python中,它只是
import itertools
。 In C++, however, I found this cppitertools . 但是,在C ++中,我找到了这个cppitertools 。 I haven't tried it, but I suppose this could work.
我没试过,但我想这可行。
Still, if you want speed, the first approch is preferred. 不过,如果你想要速度,第一个approch是首选。 Still, I think there are better solutions.
不过,我认为还有更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.