c - 给定一个变量,尝试打印位的每个组合

标签 c

假设 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/

相关文章:

c - 在 C 中使用不同的字符串?

c - 使用 C popen() : read() work, 但 fread() 没有

c - 在不知道其类型的情况下,释放为指向指针的指针分配的所有空间

c - 如果传递的参数是常量值,C 中会发生什么

c - 为什么 printf 的这种错误语法不会在 c 中产生错误?

c - C 语言中内存地址可以移植吗?

c - 如何实现位数组?

c - 最小最大分数

c - 分配动态多个数组

c - 仅使用 while 和 if 对数组进行排序