许多for循环总结为一个循环

时间:2013-04-04 20:29:59

标签: c loops for-loop iteration

我正在设计一个非常低效的幻方解算器,它会告诉你解决方案的数量到3x3平方。基本上我必须将3x3数组中的每个元素填充到一定数量(比如16)然后重置,然后移动到下一个元素并将它们填充为两个数字的数字增加。我已经设法通过使用9 for循环实现这一点,每个元素一个。但是,如果我想做一个5x5的方格,我必须编写25个循环吗?

代码的for循环部分如下。有没有办法总结这个和循环通过for循环呢?

for (sq9=1; sq9<17 ; sq9++) {
     for (sq8=1; sq8<17 ; sq8++) {
          for (sq7=1; sq7<17 ; sq7++) {
               for (sq6=1; sq6<17 ; sq6++) {
                    for (sq5=1; sq5<17 ; sq5++) {
                          for (sq4=1; sq4<17 ; sq4++) {
                               for (sq3=1; sq3<17 ; sq3++) {
                                    for (sq2=1; sq2<17 ; sq2++) {
                                         for (sq1=1; sq1<17 ; sq1++) {
                                              if  ( check_the_square() ) count++;
                                                            }}}}}}}}}}

3 个答案:

答案 0 :(得分:1)

有多种方法可以将所有这些概括为任意数量的正方形,但我想到的第一种方法是将所有正方形存储在一个数组中,然后递增它们,就像增加一个写入的数字一样。位数。

首先,让我们用一些易于编辑的常量抽象出正方形的数量及其值的范围:

#define NUM_SQUARES 9
#define MIN_VAL     1
#define MAX_VAL     16

现在,在你正在做的所有这些功能中,声明一个int的数组并将它们全部设置为MIN_VAL

int squares[NUM_SQUARES];
for (int i=0; i<NUM_SQUARES; i++) {
    squares[i] = MIN_VAL;
}

现在,我们究竟如何增加正方形?简单:在第一个值中添加一个;如果它溢出MAX_VAL,请将其设置为MIN_VAL并转到下一个方格。如果它没有溢出,停止,我们可以检查当前的配置。如果所有的正方形都溢出并且我们移过数组的末尾,我们知道我们已经处理了所有可能的正方形配置,我们可以结束整个事情。

代码中可能有什么样的?像这样:

int i = 0;
do {
    if (check_the_square()) count++;
    for (i=0; i<NUM_SQUARES; i++) {
        squares[i]++;
        if (squares[i] > MAX_VAL) {
            squares[i] = MIN_VAL;
        } else {
            break;
        }
    }
} while (i < NUM_SQUARES);

答案 1 :(得分:1)

有些库可以生成所有排列,但是如果你想自己做,你可以通过一组值来管理它,从所有的值开始为0并以所有值为16结束

const int SIZE = 3;
const int START_VALUE = 1;
const int FINAL_VALUE = 16;
int elements[3][3] = {START_VALUE};

然后定义一组函数来处理该数组。

// Will return false when all combinations have been tried.
bool has_next_permutation(int array[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; ++i) {
        for (int j = 0; j < SIZE; ++j) {
            if (array[i][j] != START_VALUE) {
                // We're not back to all elements being 0, so we're not done.
                return true;
            }
        }
    }
    return true;
}

// Gets the next permutation.
// Increase the first element by 1, and if it hits 17, reset it and
// increase the second element by 1, etc.
void get_next_permutation(int array[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; ++i) {
        for (int j = 0; j < SIZE; ++j) {
            array[i][j]++;
            if (array[i][j] <= FINAL_VALUE) {
                // Hasn't reached the final value yet.
                return;
            }
            array[i][j] = 0;
        }
    }
}

然后在循环中使用它:

do {
    check_the_square();
    get_next_permutation(elements);
} while (has_next_permutation(elements));   

答案 2 :(得分:0)

使用数组替换你的sq#和一个计算下一次迭代的小算法......在这里,你基本上需要一个+1运算符,用一个用9位数写的base-17中的数字... < / p>

  char sq[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
  int l = 8;
loop:
  if (l==-1) goto end;
  if (++sq[l]==18) { sq[l--]=1; goto loop; }
  check_the_square();
  l = 8;
  goto loop;
end:
  ...