繁体   English   中英

我可以在这里摆脱嵌套的for循环吗?

[英]Can I get rid of nested for loops here?

我有一个函数,它接受一个向量,并通过组合其中的所有元素返回一个向量。 现在,我有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;
}

我已经研究了迭代器,但我无法弄清楚它是否会起作用。

如果您要查找的是简单地生成字符串向量x的所有元素的排列并将这些排列存储到另一个输出向量中,则可以通过使用std :: next_permutationstd :: 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";
}    

实例

默认情况下, std::accumulate基本上调用元素上的operator + ,因此字符串会自动连接。

至于std::next_permutation ,它在链接中解释了它的作用。 基本上你想从一个排序的序列开始,并调用std::next_permutation来获得元素的下一个排列。

请注意,这不取决于“级别”的数量(如您所说)。 你可以有一个10个字符串的向量,这将正常工作(假设没有内存约束)。

如果要生成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;
}

实例

仍然有3个嵌套循环,但这适用于L的任何值 - 不仅仅是3. L> N也可以。

嗨我曾经在Python中遇到过类似的问题。

我想我的目标是有一个“ n -nested”循环,使得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 我没试过,但我想这可行。

不过,如果你想要速度,第一个approch是首选。 不过,我认为还有更好的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM