C 堆栈溢出错误,强制执行幻方。有什么可能的解决办法吗?
这里是我的问题,对于一个练习,我需要通过回溯来生成一个幻方 我认为将矩阵分配为一个向量和一个改变坐标的函数可能会很有用。你可以想象,即使有一个3x3的魔方,它也给了我一个堆栈溢出问题 调试它时,我发现它或多或少地发生在生成的一半,更准确地说是在函数C 堆栈溢出错误,强制执行幻方。有什么可能的解决办法吗?,c,stack-overflow,backtracking,magic-square,C,Stack Overflow,Backtracking,Magic Square,这里是我的问题,对于一个练习,我需要通过回溯来生成一个幻方 我认为将矩阵分配为一个向量和一个改变坐标的函数可能会很有用。你可以想象,即使有一个3x3的魔方,它也给了我一个堆栈溢出问题 调试它时,我发现它或多或少地发生在生成的一半,更准确地说是在函数chk\u magic(int*m,int n)callchange\u coord(i,j,m,n)的地方 这里是完整的代码,我在其中签署了中断程序的行 #include <stdio.h> #include <stdlib.h&g
chk\u magic(int*m,int n)
callchange\u coord(i,j,m,n)的地方代码>
这里是完整的代码,我在其中签署了中断程序的行
#include <stdio.h>
#include <stdlib.h>
int chk_magic(int*, int);
void generate_magic(int*, int, int);
int change_coord(int, int, int*, int);
int back_f;
int main()
{
int i, j, n=3, *m;
//printf("Inserisci la dimensione del quadrato: ");
//scanf("%d", &n);
m=malloc(n*n*sizeof(int*));
for(i=0; i<(n*n); i++)
{
m[i]=1;
}
printf("Generazione in corso (se la dimensione e' maggiore di 4 potrebbero volerci minuti)...\n");
generate_magic(m, n, n*n-1);
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
printf("%3d ", change_coord(i, j, m, n));
}
printf("\n");
}
return 0;
}
int chk_magic(int *m, int n)
{
int i, j, magic_n, orizzontal_buffer, vertical_buffer, flag;
flag=0;
magic_n=n*(n*n + 1)/2;
for(i=0; i<n; i++)
{
orizzontal_buffer=0;
vertical_buffer=0;
for(j=0; j<n; j++)
{
orizzontal_buffer+=change_coord(i, j, m, n); // <<-- HERE! HALP!
vertical_buffer+=change_coord(j, i, m, n);
}
if(vertical_buffer!=magic_n || orizzontal_buffer!=magic_n)
{
flag=1;
return flag;
}
}
orizzontal_buffer=0;
vertical_buffer=0;
for(i=0, j=n-1; i<n; i++, j--)
{
orizzontal_buffer=change_coord(i, i, m, n);
vertical_buffer=change_coord(i, j, m, n);
}
if(vertical_buffer!=magic_n || orizzontal_buffer!=magic_n)
{
flag=1;
}
return flag;
}
void generate_magic(int *m, int n, int pos)
{
if(m[pos]<n*n)
{
m[pos]++;
back_f=chk_magic(m, n);
if(back_f==0)
{
return;
}
generate_magic(m, n, n*n-1);
return;
}
if(m[pos]==n*n)
{
if(back_f==0)
{
return;
}
m[pos]=1;
generate_magic(m, n, pos-1);
return;
}
if(pos==-1)
{
return;
}
return;
}
int change_coord(int x, int y, int *m, int dim)
{
return m[(x*dim)+y];
}
#包括
#包括
int-chk_魔法(int*,int);
void生成_魔术(int*,int,int);
改变协调(int,int,int*,int);
int back_f;
int main()
{
int i,j,n=3,*m;
//printf(“方形尺寸插入”);
//scanf(“%d”和“&n”);
m=malloc(n*n*sizeof(int*);
对于(i=0;i这是家庭作业,所以我不打算修复您的代码…不过我会为您做一些分析,以向您展示问题。仅供参考:您真的应该学会使用调试器并跟踪代码
这里最大的问题是,您的“递归”逻辑只是在两个块之间来回反弹,没有“最低阶”,因此您用过多的函数调用填充缓冲区,并导致堆栈溢出:
void generate_magic(int *m, int n, int pos)
{
if(m[pos]<n*n)
{
m[pos]++;
back_f=chk_magic(m, n);
if(back_f==0)
{
return;
}
generate_magic(m, n, n*n-1); <--- 'Recursive' step
因此,现在我们输入代码集m[pos],从上一个值(9)返回到从(1)开始的值,然后执行“递归”步骤,使用值调用generate_magic()
(n==3
,pos=7
,和m[pos]==1
)
好的,这次我们用不同的值重新开始,对吗?第一次我们有:
n==3
和pos==8
现在我们有:
n==3
和pos==7
哦,但是当我们再次调用第一个“递归”调用时会发生什么呢
generate_magic(m, n, n*n-1);
这将使我们的下一个条目重置为:
n==3
和pos==8
这一点进展很快。迟早所有这些函数/参数对堆栈的推动都会杀死我们,因为我们进入了一个无限循环
旁注:
malloc(n*n*sizeof(int*));
您想要的是sizeof(int)
,而不是sizeof(int*)
因为你是矩阵中的字符串int
s,而不是指向int
s的指针。谢谢你,但我还是没有其他想法!这个练习的提示是:必须找到平方的递归函数必须尝试区间[1,N^2]中所有可能的矩阵.A最后一步,您只需验证矩阵是否为幻方。如果是,则停止递归并打印矩阵。此外,您可以使用辅助向量“标记”使用的值,以便函数不会多次使用组合。这意味着,如果“退出”递归,则需要回溯到“取消标记”在使用下一个值之前,这些值很抱歉翻译不好,但我还没有理解。顺便说一句,我理解了你上面写的内容。@LambertoBasti-我必须考虑一下,才能想出一个算法……使用迭代函数,这项任务会容易得多,但我建议你看一些简单的递归示例。reason你的代码不起作用是你在同一个函数中有两个完整的递归步骤…递归的思想是你在一个更复杂的任务中找到一个简单的任务。想想你的递归函数会一次又一次地运行同一个代码这一事实,所以把你想做的写在纸上。你想做一个幻方,所以您需要元素1、2和3添加到一个数字中,然后您需要元素4、5和6添加到同一个数字中,然后元素7、8、9添加到同一个数字中,等等添加到1、4和7中…所以在这个任务中寻找共性。您让我想到了类似的东西,但仍然不起作用。在调试时跟踪矩阵上的所有更改使我看到新的void基因rate\u magic\u no\u递归(int*m,int n)
生成所有可能的矩阵,但是chk\u magic
总是将其标记为非魔术。我试图理解为什么
malloc(n*n*sizeof(int*));