我在创建以下数组时遇到了一些困难。我的任务是使用递归填充一个二维数组,其中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;
}
答案 0 :(得分:1)
您希望(2^m)
和0's
的所有可能1's
组合按词汇顺序排列m
次,并且您正在使用2D数组来存储结果。
如果您只想打印0's
和1's
的所有可能组合,而不是稍后将其存储在2D数组和打印数组中,那将非常容易。
将0's
和1's
的组合存储到2D数组有点棘手,因为每个组合都是2D数组的一个元素。
您希望根据递归算法生成0's
和1's
的组合。
所以,假设您的算法在某个阶段生成 0010 组合,该组合存储在2D数组中的元素中。
下一个组合将是 0011 ,递归算法只会通过在最后一个组合中将最后一个数字从 0 更改为 1 来生成( 0011 强> 0010 强>)。
因此,这意味着每次生成组合时,您都需要将该组合复制到2D阵列中的连续位置。 对于例如如果 0010 在算法开始计算下一个组合之前存储在2D数组中的索引2处,我们需要做两件事:
(比方说,这是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
.....
.....
.....
我们需要在生成每个组合后执行此操作。 现在,我希望你得到了你犯错的地方。
很少练习可以遵循:
如果您想分配内存并将其初始化为0,请使用calloc
代替malloc
。
您为同一输入反复调用的任何数学函数,最好调用一次并将结果存储在变量中并在需要时使用该结果。
不要包含程序中不需要的任何头文件。
完成后,请务必释放程序中动态分配的内存。
我已在您的计划中进行了更正:
#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
希望这有帮助。