我需要编写一个程序,以遍历base-2(二进制)矢量的所有可能组合。如果此向量的大小为3,则可以使用三个嵌套循环来完成此操作,如下所示:
bool array[3];
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
for(int k = 0; k < 2; k++)
{
array[0] = i;
array[1] = j;
array[2] = k;
}
}
}
但是问题是在我的应用程序中,数组大小是可变的,并且基本上可以是任何数字。如果要查找12位向量的所有值,则不想编写12个嵌套循环,因此使用上面的代码是不可维护的。相反,我想出了以下解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#define SIZE 12
int main(void)
{
bool array[SIZE];
for(int i = 0; i < SIZE; i++) array[i] = 1;
int max_num = pow(2, SIZE);
for(int i = 0; i < max_num; i++)
{
if(array[0] == 0) array[0]++;
else
{
array[0] = 0;
for(int j = 1; j < SIZE; j++)
{
if(array[j] == 1) array[j] = 0;
else
{
array[j] = 1;
break;
}
}
}
for(int j = 0; j < SIZE; j++)
{
printf("%d", array[j]);
if(j != SIZE - 1) printf(", ");
else printf("\n");
}
}
}
对于我来说,相对如此简单的事情,这似乎仍然是很多代码。我的问题是:有没有更有效的方法?
答案 0 :(得分:1)
您对数组所做的事情实际上是对数组表示的数字进行递增(加一)。 让我们将增量留给编译器,并使用整数中的位。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 12
int main(void)
{
bool array[SIZE];
int max_num = 1 << SIZE;
for(int i = 0; i < max_num; i++)
{
for(int j = 0; j < SIZE; j++)
{
array[j] = (i >> j) & 1;
}
for(int j = 0; j < SIZE; j++)
{
printf("%d", array[j]);
if(j != SIZE - 1) printf(", ");
else printf("\n");
}
}
}
答案 1 :(得分:1)
正如其他人指出的那样,它实际上是在增加二进制数。但是,出于原始代码的精神,我决定不使用本地加法/增量运算符来增加向量的“欺骗”,并提出了以下建议:
#include <stddef.h>
#include <stdbool.h>
bool first(size_t size, bool array[size])
{
size_t i;
for (i = 0; i < size; i++)
{
array[i] = 0;
}
return i > 0;
}
bool next(size_t size, bool array[size])
{
size_t i;
for (i = 0; i < size && array[i]; i++)
{
array[i] = 0;
}
if (i < size)
{
array[i] = 1;
return 1;
}
return 0;
}
#include <stdio.h>
int main(void)
{
enum { SIZE = 12 };
bool array[SIZE];
bool going;
for (going = first(SIZE, array); going; going = next(SIZE, array))
{
size_t i;
for (i = 0; i < SIZE - 1; i++)
{
printf("%d, ", array[i]);
}
printf("%d\n", array[i]);
}
return 0;
}
可以轻松地在其他基地工作:
#include <stddef.h>
#include <stdbool.h>
bool first(size_t size, unsigned int array[size])
{
size_t i;
for (i = 0; i < size; i++)
{
array[i] = 0;
}
return i > 0;
}
bool next(size_t size, unsigned int array[size], unsigned int base)
{
size_t i;
for (i = 0; i < size && array[i] == base - 1; i++)
{
array[i] = 0;
}
if (i < size)
{
array[i]++;
return 1;
}
return 0;
}
#include <stdio.h>
int main(void)
{
enum { SIZE = 5 };
enum { BASE = 3 };
unsigned int array[SIZE];
bool going;
for (going = first(SIZE, array); going; going = next(SIZE, array, BASE))
{
size_t i;
for (i = 0; i < SIZE - 1; i++)
{
printf("%u, ", array[i]);
}
printf("%u\n", array[i]);
}
return 0;
}