【问题标题】:C - iterate over array of 0s & 1s as if binary numberC - 像二进制数一样迭代 0 和 1 的数组
【发布时间】:2017-10-26 12:44:06
【问题描述】:

我需要遍历 n 元素的数组(因此是动态大小),例如 4,就好像它是一个二进制数一样,从全零 ({0,0,0,0}) 开始。每次需要像二进制一样递增时,{0,0,0,0} -> {0,0,0,1} -> {0,0,1,0} -> {0,0,1,1} -> {0,1,0,0},等等...

我在生成使用数组值的算法时遇到了麻烦,我考虑过使用递归,但除了在 ifs 中进行硬编码之外找不到这样做的方法。我想我可以生成一个n-digit 数字,然后应用this post 中讨论的任何算法,但这很不优雅;当我需要使用数组时,OP 要求打印 n 位数字。

如果有人能指出我正确的方向,那就太好了。
背景:

int n;
scans("%d", &n);
int *arr = calloc(n, sizeof(int));

【问题讨论】:

  • 我想这取决于你的出发点是什么,以及你想如何迭代。例如,您是增加一个 int 然后将其转换为您需要的输出,还是需要“解析”数组以找到当前值然后增加它?
  • @Neil 我对你的意思感到困惑 :) 每次对数组进行重组(以二进制增量方式)我调用一个使用该数组中的值的函数,认为这些工作是不必要的对于这篇文章)

标签: c arrays loops recursion binary


【解决方案1】:

算法:

  • 从最右边的元素开始。
    • 如果为零,则将其设置为 1 并退出
    • 它必须是一个;将其设置为零
    • 如果您在最左边的元素,则退出。
    • 您尚未位于最左边的元素;向左移动一个元素并重复。

很抱歉,我无法提供代码示例。

【讨论】:

  • 这不是切换每个值吗?
  • @Isaiah 不,不会。在纸上试试看。 (如果将“exit”替换为“copy the rest of the numbers and you're done”,这可能是你小学学过的加法算法。)
  • 我明白了,我对以前使用的术语感到困惑:] 太好了,谢谢!
【解决方案2】:

算法:

  • 从最右边的元素开始。

  • 如果为零,则将其设置为一并退出

  • 它必须是一个;将其设置为零

  • 如果你在最左边的元素,则退出。

  • 你还没有在最左边的元素;向左移动一个元素并重复。

这是 Hymie 的算法,我会试着用它做一个代码:

#include <stdlib.h>
#include <stdio.h>

int my_algo(int *arr, int size) {
  for (int i = size - 1; i >= 0; i--) { // Start at the rightmost element
    if (arr[i] == 0) { // If it's a zero, then set it to one and exit
      arr[i] = 1;
      return 1;
    } else if (arr[i] == 1) { // If it's a one, set it to zero and continue
      arr[i] = 0;
    }
  }
  return 0; // stop the algo if you're at the left-most element
}

int main() {
    int n;
    scanf("%d", &n);
    int *arr = calloc(n, sizeof(int));
    do {
      for (int i = 0; i < n; i++) {
        putchar(arr[i] + '0');
      }
      putchar('\n');
    } while (my_algo(arr, n));
    return (0);
}

此算法是动态的,并且可以与 scanf 一起使用。 这是 4 的结果:

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

【讨论】:

    【解决方案3】:

    您似乎想要做的是实现binary addition(或更准确地说是二进制计数器),无论如何它都是使用逻辑门在CPU的数字电路中实现的。它可以使用逻辑运算的组合来完成(nandxor 准确地说)。

    但最优雅的方法根据我的优雅感是利用 CPU 的先天能力来增加数字并编写一个函数将数字分解为位数组:

    void generate_bit_array(unsigned int value, uint8_t *bit_array, unsigned int bit_count) {
        for (unsigned int i=0; i<bit_count; i++) {
            bit_array[i] = value >> (bit_count - i - 1) & 0x01;
        }
    }
    
    int main(int argc, void **argv) {
        unsigned int    i;
        uint8_t         my_array[4];
    
        /* Iterate and regenerate array's content */
        for (i=0; i<4; i++) {
            generate_bit_array(i, my_array, 4);
            /* Do something */
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      你可以这样做:

      #include <stdio.h>
      #include <stdlib.h>
      
      void gen_bit_array(int *numarr, int n, int arr_size) {
              if(n > 0) {
                      numarr[arr_size-n] = 0;
                      gen_bit_array(numarr, n-1, arr_size);
                      numarr[arr_size-n] = 1;
                      gen_bit_array(numarr, n-1, arr_size);
              } else {
                      int i;
                      for(i=0; i<arr_size; i++)
                              printf("%d", numarr[i]);
                      printf ("\n");
          }
      }
      
      int main() {
              int n,i;
              printf ("Enter array size:\n");
              scanf("%d", &n);
              int *numarr = calloc(n, sizeof(int));
              if (numarr == NULL)
                      return -1;
              gen_bit_array(numarr, n, n);
              return 0;
      }
      

      输出:

      Enter array size:
      2
      00
      01
      10
      11
      
      Enter array size:
      4
      0000
      0001
      0010
      0011
      0100
      0101
      0110
      0111
      1000
      1001
      1010
      1011
      1100
      1101
      1110
      1111
      

      【讨论】:

        【解决方案5】:

        如果我对您的理解正确,那么您需要的是以下内容

        #include <stdio.h>
        
        #define N   4
        
        void next_value( unsigned int a[], size_t n )
        {
            unsigned int overflow = 1;
        
            for ( size_t i = n; i != 0 && overflow; i-- )
            {
                overflow = ( a[i-1] ^= overflow ) == 0;
            }
        }
        
        int empty( const unsigned int a[], size_t n )
        {
            while ( n && a[n-1] == 0 ) --n;
        
            return n == 0;
        }
        
        int main(void)
        {
            unsigned int a[N] = { 0 };
        
            do 
            {
                for ( size_t i = 0; i < N; i++ ) printf( "%i ", a[i] );
                putchar( '\n' );
                next_value( a, N );
            } while ( !empty( a, N ) );
        
            return 0;
        }
        

        程序输出是

        0 0 0 0 
        0 0 0 1 
        0 0 1 0 
        0 0 1 1 
        0 1 0 0 
        0 1 0 1 
        0 1 1 0 
        0 1 1 1 
        1 0 0 0 
        1 0 0 1 
        1 0 1 0 
        1 0 1 1 
        1 1 0 0 
        1 1 0 1 
        1 1 1 0 
        1 1 1 1 
        

        或者您可以编写计算下一个值的函数,如果下一个值等于 0,则该函数返回 0。

        例如

        #include <stdio.h>
        #include <stdlib.h>
        
        int next_value( unsigned int a[], size_t n )
        {
            unsigned int overflow = 1;
        
            for ( ; n != 0 && overflow; n-- )
            {
                overflow = ( a[n-1] ^= overflow ) == 0;
            }
        
            return  overflow == 0;
        }
        
        int main(void)
        {
            size_t n;
        
            printf( "Enter the length of the binary number: " );
            if ( scanf( "%zu", &n ) != 1 ) n = 0;
        
            unsigned int *a = calloc( n, sizeof( unsigned int ) );
        
            do 
            {
                for ( size_t i = 0; i < n; i++ ) printf( "%i ", a[i] );
                putchar( '\n' );
            } while ( next_value( a, n ) );
        
            free( a );
        
            return 0;
        }
        

        程序输出可能看起来像

        Enter the length of the binary number: 3
        0 0 0 
        0 0 1 
        0 1 0 
        0 1 1 
        1 0 0 
        1 0 1 
        1 1 0 
        1 1 1 
        

        【讨论】:

          【解决方案6】:

          不需要算法,你可以构建一个函数,

          如果数组是固定大小,这是一个好主意:

          1. 构建一个接收数组的函数
          2. 为此函数创建一个本地积分器
          3. 将整数的位值设置为数组的单元格值
          4. 增加积分器
          5. 将数组值设置为匹配整数的每个位

          所有这些过程都可以使用移位(>>

          【讨论】:

          • 它是动态大小的,但我会更新我的问题以更清楚地反映这一点
          猜你喜欢
          • 2017-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-25
          • 2013-12-16
          • 1970-01-01
          • 1970-01-01
          • 2021-10-20
          相关资源
          最近更新 更多