动态嵌套循环(C ++)

时间:2015-03-18 19:01:30

标签: c++ loops nested

您好我正在寻找一种以一般方式编写此C ++代码的方法,因此如果需要20列,我将不必为循环编写20个:

for(int i=1; i<6; i++) {
    for(int j=i; j<6; j++) {
        for(int k=j; k<6; k++) {
            for(int m=k; m<6; m++) {
                std::cout << i << j << k << m << std::endl;
            }
        }
    }
}

重要的是我的号码遵循&gt; =订单。 我非常感谢任何帮助。

5 个答案:

答案 0 :(得分:1)

这个递归函数应该有效:

#include <iostream>

bool inc( int *indexes, int limit, int n )
{
    if( ++indexes[n] < limit )
        return true;
    if( n == 0 ) return false;
    if( inc( indexes, limit, n-1 ) ) {
        indexes[n] = indexes[n-1];
        return true;
    }
    return false;

}

int main()
{
    const size_t N=3;
    int indexes[N];
    for( size_t i = 0; i < N; ++i ) indexes[i] = 1;

    do {
        for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
        std::cout << std::endl;
    } while( inc( indexes, 6, N-1 ) );
    return 0;
}

live example

答案 1 :(得分:1)

这里的设计很简单。我们采用std::vector每个包含维度计数和std::vector包含每个维度的当前索引。

advance将当前的维度索引包推进amt(默认为1)。

void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
  if (indexes.size() < counts.size())
    indexes.resize(counts.size());
  for (size_t i = 0; i < counts.size(); ++i ) {
    indexes[i]+=amt;
    if (indexes[i] < counts[i])
      return;
    assert(counts[i]!=0);
    amt = indexes[i]/counts[i];
    indexes[i] = indexes[i]%counts[i];
  }
  // past the end, don't advance:
  indexes = counts;
}

它为我们提供了通用n维坐标的高级函数。

接下来,测试所需限制的过滤器:

bool vector_ascending( std::vector<size_t> const& v ) {
  for (size_t i = 1; (i < v.size()); ++i) {
    if (v[i-1] < v[i]) {
      return false;
    }
  }
  return true;
}

然后使用上面的for循环:

void print_a_lot( std::vector<size_t> counts ) {
  for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
    // check validity
    if (!vector_ascending(v))
      continue;
    for (size_t x : v)
      std::cout << (x+1);
    std::cout << std::endl;
  }
}

live example

不需要递归。

上面的缺点是它生成6 ^ 20个元素,然后过滤。我们不想制作那么多元素。

void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
  if (indexes.size() < counts.size())
    indexes.resize(counts.size());
  for (size_t i = 0; i < counts.size(); ++i ) {
    indexes[i]+=amt;
    if (indexes[i] < counts[i])
    {
      size_t min = indexes[i];
      // enforce <= ordering:
      for (size_t j = i+i; j < counts.size(); ++j) {
        if (indexes[j]<min)
          indexes[j]=min;
        else
          break; // other elements already follow <= transitively
      }
      assert(vector_ascending(indexes));
      return;
    }
    assert(counts[i]!=0);
    amt = indexes[i]/counts[i];
    indexes[i] = indexes[i]%counts[i];
  }
  // past the end, don't advance:
  indexes = counts;
}

应该在没有先前版本的vector_ascending检查的情况下执行此操作。 (我离开了断言进行测试)。

答案 2 :(得分:0)

此功能适用于我,但如果你想完成它,请不要用20来调用它。

#include <list>
#include <iostream>

std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
    if(counter == 0)
    {
        return inputlist;
    }
    else
    {
        std::list<std::list<int>> outputlist;
        for(std::list<int> oldlist : inputlist)
        {
            for(int i = 1; i<6; i++)
            {
                std::list<int> newlist = oldlist;
                newlist.push_back(i);
                outputlist.push_back(newlist);
            }
        }
        return fun(outputlist, counter - 1);
    }
}

int main()
{
    std::list<int> somelist;
    std::list<std::list<int>> listlist;
    listlist.push_back(somelist);
    std::list<std::list<int>> manynumbers = fun (listlist,5);
    for (std::list<int> somenumbers : manynumbers)
    {
        for(int k : somenumbers)
        {
            std::cout<<k;
        }
        std::cout<<std::endl;
    }
    return 0;
}

答案 3 :(得分:0)

与Processing(java)相同:

void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
  /*
    targetLevel is the wanted level (20 in your case)
    actualLevel starts from 1
    min starts from 1
    max is the max number displayed (6 in your case)
    prefix starts from blank
    see usage bellow (in setup function)
  */
  for(int m=min; m<max; m++) {
    if(targetLevel==actualLevel)
    {
      println(prefix+ " " + m);
    }
    else
    {
      loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
    }
  }
}

void setup(){

  loopFunction(10,1,1,6,"");

}

答案 4 :(得分:0)

好吧,我写作答案的速度不是最快......当我开始时,没有其他答案。无论如何,这是我的版本:

#include <iostream>
#include <vector>
using namespace std;

class Multiindex {
    public:
        typedef std::vector<int> Index;
        Multiindex(int dims,int size) : 
             dims(dims),size(size),index(Index(dims,0)){}
        void next(){
            int j=dims-1;
            while (nextAt(j) && j >= 0){j--;}
        }
        Index index;
        bool hasNext(){return !(index[0]==size-1);}
    private:
        bool nextAt(int j){
            index[j] = index[j]+1;
            bool overflow = (index[j]==size);
            if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
            return overflow;
        }
    int dims;
    int size;
};

int main() {
   Multiindex m(4,6);
   while (m.hasNext()){
       cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
       m.next();
   }
   cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
   return 0;
}