我正在设计一个非常低效的幻方解算器,它会告诉你解决方案的数量到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++;
}}}}}}}}}}
答案 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:
...