二维数组C中的布尔表

时间:2017-10-29 17:11:16

标签: c recursion

我在创建以下数组时遇到了一些困难。我的任务是使用递归填充一个二维数组,其中0和1的所有可能组合按词汇顺序进行m次。从数学角度讲,有2 ^ m个组合。我的程序只用相同的顺序0 1 0 1填充数组的前3行,然后只打印其余行0 0 0 0。

实施例 M = 4

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

这是我的代码到目前为止,如果有人能够纠正它并向我解释我做错了什么,我会感激,因为我无法自己发现错误

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

void *safeMalloc(int n) {
    void *p = malloc(n);
    if (p == NULL) {
        printf("Error: malloc(%d) failed. Out of memory?\n", n);
        exit(EXIT_FAILURE);
    }
    return p;
}


void combine(int** arrTF,int m,int n,int row,int col){
    if(m==0){
        if(row<pow(2,m)){
            row++;
            combine(arrTF,n,n,row,0);
        }else{
            return;
        }
    }else{
        arrTF[row][col]=0;
        col++;
        combine(arrTF,m-1,n,row,col);

        arrTF[row][col]=1;
        col++;
        combine(arrTF,m-1,n,row,col);
    }

}



int main(int argc, char *argv[]) {
    int m
    scanf("%d",&m);


    int** arrTF;

    arrTF = safeMalloc(pow(2,m)*sizeof(int *));
    for (int r=0; r < pow(2,m); r++) {
        arrTF[r] = safeMalloc(m*sizeof(int));
    }


    for(int i=0;i<pow(2,m);i++){
        for(int j=0;j<m;j++){
            arrTF[i][j]=0;
        }
    }

    combine(arrTF,m,m,0,0);

    for(int i=0;i<pow(2,m);i++){
        for(int j=0;j<m;j++){
            printf("%d ",arrTF[i][j]);
        }
        printf("\n");
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

您希望(2^m)0's的所有可能1's组合按词汇顺序排列m次,并且您正在使用2D数组来存储结果。 如果您只想打印0's1's的所有可能组合,而不是稍后将其存储在2D数组和打印数组中,那将非常容易。

0's1's的组合存储到2D数组有点棘手,因为每个组合都是2D数组的一个元素。 您希望根据递归算法生成0's1's的组合。 所以,假设您的算法在某个阶段生成 0010 组合,该组合存储在2D数组中的元素中。 下一个组合将是 0011 ,递归算法只会通过在最后一个组合中将最后一个数字从 0 更改为 1 来生成( 0011 强> 0010 )。

因此,这意味着每次生成组合时,您都需要将该组合复制到2D阵列中的连续位置。 对于例如如果 0010 在算法开始计算下一个组合之前存储在2D数组中的索引2处,我们需要做两件事:

  1. 将索引2的元素复制到索引3
  2. 增加行号,以便最后一个组合完好
  3. (比方说,这是2D数组)

    | 0 | 0 | 0 | 0 | index 0

    | 0 | 0 | 0 | 1 | index 1

    | 0 | 0 | 1 | 0 | index 2 ---&gt;将其复制到其连续位置(即索引3)

    | 0 | 0 | 1 | 1 | index 3 ---&gt;最后一个组合(索引2)和最后一个数字从0更改为1

    .....

    .....

    .....

    我们需要在生成每个组合后执行此操作。 现在,我希望你得到了你犯错的地方。

    很少练习可以遵循:

    1. 如果您想分配内存并将其初始化为0,请使用calloc代替malloc

    2. 您为同一输入反复调用的任何数学函数,最好调用一次并将结果存储在变量中并在需要时使用该结果。

    3. 不要包含程序中不需要的任何头文件。

    4. 完成后,请务必释放程序中动态分配的内存。

    5. 我已在您的计划中进行了更正:

      #include <stdio.h>
      #include <stdlib.h>
      #include <math.h>
      
      void *safeMalloc(size_t n, size_t size) {
          void *p = calloc(n, size);
          if (p == NULL) {
              printf("Error: calloc(%zu) failed. Out of memory!\n", n);
              exit(EXIT_FAILURE);
          }
          return p;
      }
      
      void deallocate(int ** ptr, int row) {
          for(int i = 0; i<row; i++)
                  free(ptr[i]);
          free(ptr);
      }
      
      void combine(int **arrTF, int m, int max_col, int max_row) {
          static int row;
          if(m==0){
              int i;
              if (row<(max_row - 1))
              {
                  for(i=0; i<max_col; i++)
                      arrTF[row+1][i] = arrTF[row][i];
              }
              row++;
              return;
          } else {
              arrTF[row][max_col-m] = 0;
              combine(arrTF, m-1, max_col, max_row);
      
              arrTF[row][max_col-m] = 1;
              combine(arrTF, m-1, max_col, max_row);
          }
      }
      
      int main(int argc, char *argv[]) {
          int** arrTF;
          int m, max_row;
      
          printf ("Enter number: \n");
          scanf("%d", &m);
      
          max_row = pow(2, m);
      
          arrTF = safeMalloc(max_row, sizeof(int *));
          for (int r=0; r<max_row; r++) {
              arrTF[r] = safeMalloc(m, sizeof(int));
          }
      
          combine(arrTF, m, m, max_row);
      
          for(int i=0; i<max_row; i++) {
              for(int j=0; j<m; j++) {
                  printf("%d ", arrTF[i][j]);
              }
              printf("\n");
          }
          deallocate(arrTF, max_row);
          return 0;
      }
      

      输出:

      $ ./a.out
      Enter number: 
      2
      0 0 
      0 1 
      1 0 
      1 1 
      
      $ ./a.out
      4
      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 
      

      希望这有帮助。