C++ 创建N个嵌套的for循环

C++ 创建N个嵌套的for循环,c++,algorithm,for-loop,recursion,nested-loops,C++,Algorithm,For Loop,Recursion,Nested Loops,有没有一种方法可以创建表单的循环 for(int i = 0; i < 9; ++i) { for(int j = 0; j < 9; ++i) { //... for(int k = 0; k < 9; ++k) { //N-th loop for(int i=0;itheNest;i--){ idxes[i]=maxes[i]-1; } } } #endif//NESTEDLOOP\u水电站 下面是一个具有预期输出的示例: #includ

有没有一种方法可以创建表单的循环

for(int i = 0; i < 9; ++i) {
    for(int j = 0; j < 9; ++i) {
    //...
        for(int k = 0; k < 9; ++k) { //N-th loop
for(int i=0;i<9;++i){
对于(int j=0;j<9;++i){
//...
对于(int k=0;k<9;++k){//N次循环

在编译时不知道N。理想情况下,我正在尝试找出一种方法,通过数字向量的单独元素循环,以创建每个可能的数字,如果用不同的数字替换一定数量的数字。

您可以使用递归代替基本条件-

void doRecursion(int baseCondition){

   if(baseCondition==0) return;

   //place your code here

   doRecursion(baseCondition-1);
}  

现在,您不需要在编译时提供
baseCondition
值。您可以在调用
doRecursion()
方法时提供该值。

您可以将递归调用用作:

void runNextNestedFor(std::vector<int> counters, int index)
{
     for(counters[index] = 0; counters[index] < 9; ++counters[index]) {
       // DO
       if(index!=N)
          runNextNestedFor(counters, index+1);
     }
}
void runNextNestedFor(std::vector counters,int index)
{
用于(计数器[索引]=0;计数器[索引]<9;++计数器[索引]){
//做
如果(索引!=N)
运行NEXTNESTEDFOR(计数器,索引+1);
}
}
第一次称之为:

std::vectors<int> counters(N);
runNextNestedFor(counters, 0);
std::向量计数器(N);
runNextNestedFor(计数器,0);

您可以使用递归函数:

void loop_function(/*params*/,int N){
for(int i=0;i<9;++i){
    if(N>0) loop_function(/*new params*/,N-1);
}
void循环函数(/*params*/,int N){
对于(int i=0;i0)循环函数(/*新参数*/,N-1);
}
这将递归调用循环函数N次,而每个函数将迭代调用循环函数


以这种方式编程可能有点困难,但它应该可以实现您想要的功能

这里有一个很好的多索引小类,可以通过基于范围的for循环进行迭代:

#include<array>

template<int dim>
struct multi_index_t
{
    std::array<int, dim> size_array;
    template<typename ... Args>
    multi_index_t(Args&& ... args) : size_array(std::forward<Args>(args) ...) {}

    struct iterator
    {
        struct sentinel_t {};

        std::array<int, dim> index_array = {};
        std::array<int, dim> const& size_array;
        bool _end = false;

        iterator(std::array<int, dim> const& size_array) : size_array(size_array) {}

        auto& operator++()
        {
            for (int i = 0;i < dim;++i)
            {
                if (index_array[i] < size_array[i] - 1)
                {
                    ++index_array[i];
                    for (int j = 0;j < i;++j)
                    {
                        index_array[j] = 0;
                    }
                    return *this;
                }
            }
            _end = true;
            return *this;
        }
        auto& operator*()
        {
            return index_array;
        }
        bool operator!=(sentinel_t) const
        {
            return !_end;
        }
    };

    auto begin() const
    {
        return iterator{ size_array };
    }
    auto end() const
    {
        return typename iterator::sentinel_t{};
    }
};

template<typename ... index_t>
auto multi_index(index_t&& ... index)
{
    static constexpr int size = sizeof ... (index_t); 
    auto ar = std::array<int, size>{std::forward<index_t>(index) ...};
    return multi_index_t<size>(ar);
}

我将根据给出的示例代码的面值计算OP,并假设所要求的是一个通过任意基数-10计数的解决方案。(我是根据注释来计算的。)“理想情况下,我正试图找到一种方法,通过数字向量中的独立元素循环创建每个可能的数字”

这个解决方案有一个循环,它通过以10为底的数字向量进行计数,并将每个连续值传递给一个helper函数(doThingWithNumber)。出于测试目的,我让这个helper只需打印出数字

#include <iostream>

using namespace std;

void doThingWithNumber(const int* digits, int numDigits)
{
    int i;
    for (i = numDigits-1; i>=0; i--)
        cout << digits[i];
    cout << endl;
}

void loopOverAllNumbers(int numDigits)
{
    int* digits = new int [numDigits];
    int i;
    for (i = 0; i< numDigits; i++) 
        digits[i] = 0;

    int maxDigit = 0;
    while (maxDigit < numDigits) {
        doThingWithNumber(digits, numDigits);
        for (i = 0; i < numDigits; i++) {
            digits[i]++;
            if (digits[i] < 10)
                break;
            digits[i] = 0;
        }
        if (i > maxDigit)
            maxDigit = i;
    }
}

int main()
{
    loopOverAllNumbers(3);
    return 0;
}
#包括
使用名称空间std;
void doThingWithNumber(常量int*位数,整数位数)
{
int i;
对于(i=numDigits-1;i>=0;i--)

CUT< P>我编写了一些C++ 11代码,为自己实现了一个n-嵌套for循环。这里是代码的主要部分,可以作为一个单一的.HPP导入(我称之为NestEdLoop .HPP):

\ifndef嵌套回路\u水电站
#定义嵌套回路\u水电站
#包括
命名空间嵌套循环{
类嵌套循环{
公众:
//变数
std::向量最大值;
std::vector idxes;//最后一个元素用于边界控制
int N=0;
int nestLevel=0;
nestedLoop();
嵌套循环(int,int);
嵌套循环(int,std::vector);
无效重置(int numberOfNests,int Max);
无效重置(int numberOfNests,std::vector theMaxes);
bool next();
空跳巢(内-外);
私人:
无效清除();
};
//初始化
nestedLoop::nestedLoop(){}
nestedLoop::nestedLoop(int numberOfNests,int Max){
重置(最大嵌套数);
}
nestedLoop::nestedLoop(嵌套的整数,std::向量轴){
重置(嵌套数、坐标轴);
}
void nestedLoop::clear(){
maxes.clear();
idxes.clear();
N=0;
nestLevel=0;
}
//重置场景
void nestedLoop::reset(int numberOfNests,int Max){
std::矢量坐标轴;
对于(inti=0;i=maxes[i]){
idx[i]=0;
如果(i){//实际上,如果需要i>0
idx[i-1]+=1;
}否则{
返回false;
}
}否则{
nestLevel=i;
打破
}
}
返回true;
}
void nestedLoop::jumpNest(int-theNest){
对于(inti=N-1;i>theNest;i--){
idxes[i]=maxes[i]-1;
}
}
}
#endif//NESTEDLOOP\u水电站
下面是一个具有预期输出的示例:

#include <iostream>
#include "stlvecs.hpp"
#include "nestedLoop.hpp"

int main(){
    nestedLoop::nestedLoop looper;
    std::vector<int> maxes = {2, 3, 2, 2};
    looper.reset(4,maxes);
    int i = 0;
    while(looper.next()){
        std::cout << "Indices: " << looper.idxes << ", Last nest incremented: " << looper.nestLevel << std::endl;
        if(i == 5){
            std::cout << "...Jump Second Nest (index 1)..." << std::endl;
            looper.jumpNest(1);
        }
        i++;
    }
}

/* Expected output
Indices: 4  0 0 0 0 , Last nest incremented: 0
Indices: 4  0 0 0 1 , Last nest incremented: 3
Indices: 4  0 0 1 0 , Last nest incremented: 2
Indices: 4  0 0 1 1 , Last nest incremented: 3
Indices: 4  0 1 0 0 , Last nest incremented: 1
Indices: 4  0 1 0 1 , Last nest incremented: 3
...Jump Second Nest (index 1)...
Indices: 4  0 2 0 0 , Last nest incremented: 1
Indices: 4  0 2 0 1 , Last nest incremented: 3
Indices: 4  0 2 1 0 , Last nest incremented: 2
Indices: 4  0 2 1 1 , Last nest incremented: 3
Indices: 4  1 0 0 0 , Last nest incremented: 0
Indices: 4  1 0 0 1 , Last nest incremented: 3
Indices: 4  1 0 1 0 , Last nest incremented: 2
Indices: 4  1 0 1 1 , Last nest incremented: 3
Indices: 4  1 1 0 0 , Last nest incremented: 1
Indices: 4  1 1 0 1 , Last nest incremented: 3
Indices: 4  1 1 1 0 , Last nest incremented: 2
Indices: 4  1 1 1 1 , Last nest incremented: 3
Indices: 4  1 2 0 0 , Last nest incremented: 1
Indices: 4  1 2 0 1 , Last nest incremented: 3
Indices: 4  1 2 1 0 , Last nest incremented: 2
Indices: 4  1 2 1 1 , Last nest incremented: 3
*/
#包括
#包括“stlvecs.hpp”
#包括“nestedLoop.hpp”
int main(){
nestedLoop::nestedLoop循环器;
向量最大值={2,3,2,2};
活套复位(4,最大值);
int i=0;
while(looper.next()){
std::cout我使用这个解决方案:

unsigned int dim = 3;
unsigned int top = 5;
std::vector<unsigned int> m(dim, 0);
for (unsigned int i = 0; i < pow(top,dim); i++)
{
    // What you want to do comes here 
    //      |
    //      |
    //      v
    // -----------------------------------
    for (unsigned int j = 0; j < dim; j++)
    {
        std::cout << m[j] << ",";
    }
    std::cout << std::endl;
    // -----------------------------------

    // Increment m
    if (i == pow(top, dim) - 1) break;
    unsigned int index_to_increment = dim - 1;
    while(m[index_to_increment] == (top-1)) {
        m[index_to_increment] = 0;
        index_to_increment -= 1;
    }
    m[index_to_increment] += 1;
}
unsigned int dim=3;
无符号整数top=5;
std::向量m(dim,0);
for(无符号整数i=0;istd::你能不能对一个包含for循环的函数使用N个递归调用。为什么if和else之间有差距?我不确定它是如何工作的out@Andrew,谢谢。我已经修好了。实际上一开始没有注释(//把代码放在这里)添加注释后,我忘了删除
else
。当我尝试运行int counter=0;void loop_函数(vector&digits,int n){int index=n-1;for(digits[index]=0;digits[index]<9;++digits[index]){if(n>1)loop_函数(digits,n-1);display(digits);++counter;}int main(){vector vec(3,0);loop_函数(vec,vec.size());根据我对代码的理解,向量数字一直在变化,直到向量为{9,9},为此,在最后一个元素上执行9*9*9迭代(在两个循环中从0到9),第二次你做9*9次迭代,最后9次迭代。最后,你得到了{9,9,9}的数字向量,要得到它,你需要
#include <iostream>
#include "stlvecs.hpp"
#include "nestedLoop.hpp"

int main(){
    nestedLoop::nestedLoop looper;
    std::vector<int> maxes = {2, 3, 2, 2};
    looper.reset(4,maxes);
    int i = 0;
    while(looper.next()){
        std::cout << "Indices: " << looper.idxes << ", Last nest incremented: " << looper.nestLevel << std::endl;
        if(i == 5){
            std::cout << "...Jump Second Nest (index 1)..." << std::endl;
            looper.jumpNest(1);
        }
        i++;
    }
}

/* Expected output
Indices: 4  0 0 0 0 , Last nest incremented: 0
Indices: 4  0 0 0 1 , Last nest incremented: 3
Indices: 4  0 0 1 0 , Last nest incremented: 2
Indices: 4  0 0 1 1 , Last nest incremented: 3
Indices: 4  0 1 0 0 , Last nest incremented: 1
Indices: 4  0 1 0 1 , Last nest incremented: 3
...Jump Second Nest (index 1)...
Indices: 4  0 2 0 0 , Last nest incremented: 1
Indices: 4  0 2 0 1 , Last nest incremented: 3
Indices: 4  0 2 1 0 , Last nest incremented: 2
Indices: 4  0 2 1 1 , Last nest incremented: 3
Indices: 4  1 0 0 0 , Last nest incremented: 0
Indices: 4  1 0 0 1 , Last nest incremented: 3
Indices: 4  1 0 1 0 , Last nest incremented: 2
Indices: 4  1 0 1 1 , Last nest incremented: 3
Indices: 4  1 1 0 0 , Last nest incremented: 1
Indices: 4  1 1 0 1 , Last nest incremented: 3
Indices: 4  1 1 1 0 , Last nest incremented: 2
Indices: 4  1 1 1 1 , Last nest incremented: 3
Indices: 4  1 2 0 0 , Last nest incremented: 1
Indices: 4  1 2 0 1 , Last nest incremented: 3
Indices: 4  1 2 1 0 , Last nest incremented: 2
Indices: 4  1 2 1 1 , Last nest incremented: 3
*/
unsigned int dim = 3;
unsigned int top = 5;
std::vector<unsigned int> m(dim, 0);
for (unsigned int i = 0; i < pow(top,dim); i++)
{
    // What you want to do comes here 
    //      |
    //      |
    //      v
    // -----------------------------------
    for (unsigned int j = 0; j < dim; j++)
    {
        std::cout << m[j] << ",";
    }
    std::cout << std::endl;
    // -----------------------------------

    // Increment m
    if (i == pow(top, dim) - 1) break;
    unsigned int index_to_increment = dim - 1;
    while(m[index_to_increment] == (top-1)) {
        m[index_to_increment] = 0;
        index_to_increment -= 1;
    }
    m[index_to_increment] += 1;
}
typedef std::vector<unsigned int> ivec;
void increment_multi_index(ivec &m, ivec const & upper_bounds)
{
    unsigned int dim = m.size();
    unsigned int i = dim - 1;
    while(m[i] == upper_bounds[i] - 1 && i>0) {
        m[i] = 0;
        i -= 1;
    }
    m[i] += 1;
}

int main() {

    unsigned int dim = 3;
    unsigned int top = 5;
    ivec m(dim, 0);
    ivec t(dim, top);
    for (unsigned int i = 0; i < pow(top,dim); i++)
    {
        // What you want to do comes here 
        //      |
        //      |
        //      v
        // -----------------------------------
        for (unsigned int j = 0; j < dim; j++)
        {
            std::cout << m[j] << ",";
        }
        std::cout << std::endl;
        // -----------------------------------

        // Increment m
        increment_multi_index(m, t);
    }

}