假设 combinationlength
=4。
我的逻辑是创建 array {0,0,0,0}
将 1
添加到最后一个元素,直到第一个元素获得值 1
。到那时,如果添加 1
array[3]
最终得到 2
结果,则将其设为 0
然后在给定 counter 变量
的情况下遍历数组(反向),每个第一个非 1
元素使其成为 0
,同时使所有元素都在值之前第一个非 1
等于 0
。这是 8 次重复。我有多接近?有人可以帮我完成这个吗?
此外,由于某种原因它没有运行。2 秒后没有打印并结束。
我只是注意到我跳过了一步,但无论如何。
我希望在每次迭代中都有一个像序列一样的数组。而不是添加 printf("0");以及类似的快捷方式。
void print(int combinationlength){
int i,j,count;
int a=combinationlength-1;
int c=combinationlength-1;
int b;
int array[4]={0};
while(array[0]!=1){
array[a]++;
if(array[a]==2){
array[a]=0;
for(b=a;b<=c-1;b--){
if(array[b]==0)
array[b]=1;
}
c--;
}
for(count=0;count<combinationlength;count++){
printf("%d",array[count]);
}
printf("\n");
}
return 0;
}
更新:(也更新了我在这个 ^^ 代码块上方的解释)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
int i,j,count;
int a=4-1;
int c=4-1;
int b;
int array[4]={0};
while(array[0]!=1){
array[a]++;
if(array[a]==2){
array[a]=0;
for(b=a-1;b>c-1;b--){
if(array[b]==0) array[b]=1;
else array[b]=0;
}
c--;
}
for(count=0;count<4;count++){
printf("%d",array[count]);
}
printf("\n");
}
return 0;
}
硬编码数字 4 应该是输入变量。
最佳答案
所以,我仍然不能完全确定我理解您想要什么。如果我理解正确的话,您需要一定长度的每个位组合(即 0 和 1)。在数组中手动进行加法感觉非常浪费,所以让我们改用 CPU 已经提供的东西——整数加法。
一个示例程序,打印一定长度的所有组合看起来像这样:
#include <stdio.h>
void print(int len){
for (unsigned long sortOfAnArray = 0; sortOfAnArray < (1U << len); sortOfAnArray++) {
for (int i = len - 1; i >= 0; i--) {
printf("%lu", (sortOfAnArray >> i) & 1);
}
printf("\n");
}
}
int main(void) {
print(5);
return 0;
}
为了解释这些步骤,sortOfAnArray
是我们的整数,以二进制形式存储,我们在每次迭代时将其加 1,以便我们得到不同的组合。
为了打印它,我们必须单独访问元素,我们结合使用移位和逻辑和 (sortOfAnArray >> i) & 1
来做到这一点.因此,我们将数组中的位向右移动 i,并检查它是否在第一个位置有 1,换句话说,我们检查是否为 sortOfAnArray[i]==1
。 (如果这是一个数组)。
我们使用 unsigned 是因为标准和 long 以防你想要最多 64 位可用(尽管 long long
会更安全)。
编辑
进一步解释我们如何从整数中提取位。
假设我们有整数
`unsigned long long foo = 27`
如果我们查看它的位表示,我们会得到 00...011011,其中总位数为 64,但只有很多零,因此有很多点。现在,假设我们想知道右起第 1 位的值。我们可以通过使用逻辑与操作来找出这一点
`foo & 1`
这会将逻辑与应用于两个整数(foo 和 1)中相同位置的每一对位,在这种情况下,这会给我们 1:
foo -- 00...011011
1 -- 00...000001
foo & 1 -- 00...000001
如果 foo 最右边的位是 0,结果将是 0,所以这实际上允许我们读取第一位是设置为 0 还是 1。
我们如何将其推广到其他位?
我们有两个选择,我们可以移动 1 中的位(1 << n
将 1 位向左移动 n),如果我们使用逻辑然后,如果 foo 在中有 0,我们将得到 0第 n 个位置或某个非零值 (2^n),如果它有 1。
另一种选择是将 foo 的位向右移动,这样做的好处是如果 foo 在第 n 个位置有一个 1,结果现在将是 1 而不是 2^n,而如果它是 0,结果仍然是 0。除此之外,这两种方法是等效的。
这就是我们得出最终解决方案的方式,即访问第 n 个元素(从 0 开始计数),如下所示:
(foo >> n) & 1
我们将 foo 的位向右移动 n 并查看第一位是否设置为 0 或 1。本质上,整数存储 64 位(当然我们不需要使用所有位)与我们在数组中执行此操作的方式相同,但该方法效率更高。除其他外,我们不需要像您最初尝试的那样为数组实现我们自己的添加。
关于c - 给定一个变量,尝试打印位的每个组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51096034/