为什么我更改数组大小后结果会发生变化?
Why the result changes after i change the size of array?
我已经完成了一个程序,该程序将数字 n
作为输入,然后 return 一个方阵 n*n
,其中 属性 所有行、列和对角线的总和相同。
该项目没有问题,我尝试尽可能地优化它,从算法到为此使用特定的数据类型(在我的情况下 unsigned short
,因为我不需要更大的存储空间)。
毕竟我想看看性能,我想尝试更大的数字,比如 100,200,等等;
但是当我试图改变矩阵的存储时,程序无法正常工作,return用 0 编辑了一个矩阵,总和很奇怪。
我不明白这个错误是从哪里来的。
#include <stdio.h>
#include <stdlib.h>
unsigned short a[100][100], i = 0, j = 0, n, suma[100];
void next_b(unsigned short *i, unsigned short *j); // find the properly i and j
void completare(unsigned short i, unsigned short j); // completes the matrix after i find the i and j
void tipar(); // print the matrix
int suma_linie(unsigned short x); //sum of a row
int suma_coloana(unsigned short y); //sum of a column
int suma_diagonala_principala(); //first diagonal
int suma_diagonala_secundara(); //second one
int main()
{
scanf("%hu", &n);
system("cls");
j = n / 2 - 1;
a[0][j] = 4;
a[0][j + 1] = 1;
a[1][j] = 2;
a[1][j + 1] = 3;
suma[0] = 5;
suma[1] = 5;
suma[n + j] = 6;
suma[n + j + 1] = 4;
for (int x = 2; x <= (n / 2) * (n / 2); x++)
{
next_b(&i, &j);
a[i][j] = x;
completare(i, j);
}
tipar();
//for(int x=0;x<n;x++){
//
// printf("suma de pe linia %d este: %d\n",x,suma_linie(x));
// printf("suma de pe coloana %d este: %d\n\n",x,suma_coloana(x));
//}
//printf("suma de pe daig principala este: %d\n\n",suma_diagonala_principala());
// printf("suma de pe daig secundara este: %d\n\n",suma_diagonala_secundara());
for (int x = 0; x < 2 * n + 2; x++)
{
if (x < n)
{
printf("suma de pe linia %d este %hu\n", x, suma[x]);
}
else if (x < 2 * n)
{
printf("suma de pe coloana %d este %hu\n", x % n, suma[x]);
}
else if (x == 2 * n)
{
printf("suma de pe diag principala este %hu\n", suma[x]);
}
else
{
printf("suma de pe diag secundara este %hu\n", suma[x]);
}
}
return 0;
}
void tipar()
{
for (int k = 0; k < n; k++)
{
for (int l = 0; l < n; l++)
{
if (a[k][l] < 10)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] <= 99)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] < 1000)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] < 10000)
{
printf("%d ", a[k][l]);
}
}
printf("\n");
for (int z = 0; z <= 6 * n - 1; z++)
{
printf("-");
}
printf("\n");
}
printf("\n");
}
void next_b(unsigned short *i, unsigned short *j)
{
if (*i - 2 < 0)
{
if (a[n - 2][*j + 2] == 0 && *j + 2 <= n - 2)
{
// printf("cazul 2\n");
*i = n - 2;
*j += 2;
return;
}
else if (a[*i - 2][*j] == 0)
{
// printf("cazul 7\n");
*i += 2;
return;
}
}
else
{
if (*j == n - 2)
{ //printf("cazul 3\n");
*i -= 2;
*j = 0;
return;
}
else if (a[*i - 2][*j + 2] != 0)
{
//printf("cazul 4\n");
*i += 2;
}
else if (a[*i - 2][*j + 2] == 0)
{
// printf("cazul 5\n");
*i -= 2;
*j += 2;
}
}
}
void completare(unsigned short i, unsigned short j)
{
if (i <= n / 2)
{ //////////// l
if (i == n / 2 - 1 && j == n / 2 - 1)
{
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j] = 4 * a[i][j] - 2;
a[i + 1][j + 1] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
else
{
a[i][j] = 4 * a[i][j];
a[i][j + 1] = a[i][j] - 3;
a[i + 1][j] = a[i][j] - 2;
a[i + 1][j + 1] = a[i][j] - 1;
}
}
else if (i == n / 2 + 1)
{ ///////////// u
if (j == n / 2 - 1)
{
a[i][j] = 4 * a[i][j];
a[i][j + 1] = a[i][j] - 3;
a[i + 1][j] = a[i][j] - 2;
a[i + 1][j + 1] = a[i][j] - 1;
}
else
{
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j] = 4 * a[i][j] - 2;
a[i + 1][j + 1] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
}
else
{ ///////x
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j + 1] = 4 * a[i][j] - 2;
a[i + 1][j] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
suma[i] += a[i][j] + a[i][j + 1];
suma[i + 1] += a[i + 1][j] + a[i + 1][j + 1];
suma[n + j] += a[i][j] + a[i + 1][j];
suma[n + j + 1] += a[i][j + 1] + a[i + 1][j + 1];
if (i == j)
{
suma[2 * n] += a[i][j] + a[i + 1][j + 1];
}
if (i + j + 1 == n - 1)
{
suma[2 * n + 1] += a[i + 1][j] + a[i][j + 1];
}
}
int suma_linie(unsigned short x)
{
int s = 0;
for (int y = 0; y < n; y++)
{
s += a[x][y];
}
return s;
}
int suma_coloana(unsigned short y)
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][y];
}
return s;
}
int suma_diagonala_principala()
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][x];
}
return s;
}
int suma_diagonala_secundara()
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][n - x - 1];
}
return s;
}
代码是用我在 Wikipedia-Magic Square.
上找到的算法求解的
在上面的 cod 中,如果我尝试将 suma
大小更改为 200 或任何其他值,程序将运行奇怪并且 returns 愚蠢的事情。
即使我将 a
尺寸设置得更高也是有效的。
我用了两种方法来查看总和,一种使用预定义函数,另一种将矩阵元素添加到 suma
,使用的函数 int
,另一种方法使用 unsigned short
如果重要的话。
我检查了你的代码,发现了一些问题。我试过 n = 90
.
for(int x=2; x<=(n/2)*(n/2); x++)
{
next_b(&i,&j);
a[i][j]=x;
completare(i,j);
}
如果你检查这段代码,那么你可以看到 i, j
的值何时相应地变为 0, 2
然后它会转到 next_b(i, j)
方法。还有一些行试图访问 negative 索引。所以它抛出异常。
喜欢 -
else if(a[*i-2][*j]==0) // here
{
// printf("cazul 7\n");
*i+=2;
return;
}
................................................
if(*j==n-2)
{
//printf("cazul 3\n");
*i-=2;
*j=0;
return;
}
else if (a[*i-2][*j+2]!=0) // here
{
//printf("cazul 4\n");
*i+=2;
}
else if(a[*i-2][*j+2]==0) // here
{
//printf("cazul 5\n");
*i-=2;
*j+=2;
}
尝试修复这些负索引然后它应该工作(假设你的方法是正确的)。
我已经完成了一个程序,该程序将数字 n
作为输入,然后 return 一个方阵 n*n
,其中 属性 所有行、列和对角线的总和相同。
该项目没有问题,我尝试尽可能地优化它,从算法到为此使用特定的数据类型(在我的情况下 unsigned short
,因为我不需要更大的存储空间)。
毕竟我想看看性能,我想尝试更大的数字,比如 100,200,等等; 但是当我试图改变矩阵的存储时,程序无法正常工作,return用 0 编辑了一个矩阵,总和很奇怪。
我不明白这个错误是从哪里来的。
#include <stdio.h>
#include <stdlib.h>
unsigned short a[100][100], i = 0, j = 0, n, suma[100];
void next_b(unsigned short *i, unsigned short *j); // find the properly i and j
void completare(unsigned short i, unsigned short j); // completes the matrix after i find the i and j
void tipar(); // print the matrix
int suma_linie(unsigned short x); //sum of a row
int suma_coloana(unsigned short y); //sum of a column
int suma_diagonala_principala(); //first diagonal
int suma_diagonala_secundara(); //second one
int main()
{
scanf("%hu", &n);
system("cls");
j = n / 2 - 1;
a[0][j] = 4;
a[0][j + 1] = 1;
a[1][j] = 2;
a[1][j + 1] = 3;
suma[0] = 5;
suma[1] = 5;
suma[n + j] = 6;
suma[n + j + 1] = 4;
for (int x = 2; x <= (n / 2) * (n / 2); x++)
{
next_b(&i, &j);
a[i][j] = x;
completare(i, j);
}
tipar();
//for(int x=0;x<n;x++){
//
// printf("suma de pe linia %d este: %d\n",x,suma_linie(x));
// printf("suma de pe coloana %d este: %d\n\n",x,suma_coloana(x));
//}
//printf("suma de pe daig principala este: %d\n\n",suma_diagonala_principala());
// printf("suma de pe daig secundara este: %d\n\n",suma_diagonala_secundara());
for (int x = 0; x < 2 * n + 2; x++)
{
if (x < n)
{
printf("suma de pe linia %d este %hu\n", x, suma[x]);
}
else if (x < 2 * n)
{
printf("suma de pe coloana %d este %hu\n", x % n, suma[x]);
}
else if (x == 2 * n)
{
printf("suma de pe diag principala este %hu\n", suma[x]);
}
else
{
printf("suma de pe diag secundara este %hu\n", suma[x]);
}
}
return 0;
}
void tipar()
{
for (int k = 0; k < n; k++)
{
for (int l = 0; l < n; l++)
{
if (a[k][l] < 10)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] <= 99)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] < 1000)
{
printf(" %d |", a[k][l]);
}
else if (a[k][l] < 10000)
{
printf("%d ", a[k][l]);
}
}
printf("\n");
for (int z = 0; z <= 6 * n - 1; z++)
{
printf("-");
}
printf("\n");
}
printf("\n");
}
void next_b(unsigned short *i, unsigned short *j)
{
if (*i - 2 < 0)
{
if (a[n - 2][*j + 2] == 0 && *j + 2 <= n - 2)
{
// printf("cazul 2\n");
*i = n - 2;
*j += 2;
return;
}
else if (a[*i - 2][*j] == 0)
{
// printf("cazul 7\n");
*i += 2;
return;
}
}
else
{
if (*j == n - 2)
{ //printf("cazul 3\n");
*i -= 2;
*j = 0;
return;
}
else if (a[*i - 2][*j + 2] != 0)
{
//printf("cazul 4\n");
*i += 2;
}
else if (a[*i - 2][*j + 2] == 0)
{
// printf("cazul 5\n");
*i -= 2;
*j += 2;
}
}
}
void completare(unsigned short i, unsigned short j)
{
if (i <= n / 2)
{ //////////// l
if (i == n / 2 - 1 && j == n / 2 - 1)
{
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j] = 4 * a[i][j] - 2;
a[i + 1][j + 1] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
else
{
a[i][j] = 4 * a[i][j];
a[i][j + 1] = a[i][j] - 3;
a[i + 1][j] = a[i][j] - 2;
a[i + 1][j + 1] = a[i][j] - 1;
}
}
else if (i == n / 2 + 1)
{ ///////////// u
if (j == n / 2 - 1)
{
a[i][j] = 4 * a[i][j];
a[i][j + 1] = a[i][j] - 3;
a[i + 1][j] = a[i][j] - 2;
a[i + 1][j + 1] = a[i][j] - 1;
}
else
{
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j] = 4 * a[i][j] - 2;
a[i + 1][j + 1] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
}
else
{ ///////x
a[i][j + 1] = 4 * a[i][j];
a[i + 1][j + 1] = 4 * a[i][j] - 2;
a[i + 1][j] = 4 * a[i][j] - 1;
a[i][j] = 4 * a[i][j] - 3;
}
suma[i] += a[i][j] + a[i][j + 1];
suma[i + 1] += a[i + 1][j] + a[i + 1][j + 1];
suma[n + j] += a[i][j] + a[i + 1][j];
suma[n + j + 1] += a[i][j + 1] + a[i + 1][j + 1];
if (i == j)
{
suma[2 * n] += a[i][j] + a[i + 1][j + 1];
}
if (i + j + 1 == n - 1)
{
suma[2 * n + 1] += a[i + 1][j] + a[i][j + 1];
}
}
int suma_linie(unsigned short x)
{
int s = 0;
for (int y = 0; y < n; y++)
{
s += a[x][y];
}
return s;
}
int suma_coloana(unsigned short y)
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][y];
}
return s;
}
int suma_diagonala_principala()
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][x];
}
return s;
}
int suma_diagonala_secundara()
{
int s = 0;
for (int x = 0; x < n; x++)
{
s += a[x][n - x - 1];
}
return s;
}
代码是用我在 Wikipedia-Magic Square.
上找到的算法求解的在上面的 cod 中,如果我尝试将 suma
大小更改为 200 或任何其他值,程序将运行奇怪并且 returns 愚蠢的事情。
即使我将 a
尺寸设置得更高也是有效的。
我用了两种方法来查看总和,一种使用预定义函数,另一种将矩阵元素添加到 suma
,使用的函数 int
,另一种方法使用 unsigned short
如果重要的话。
我检查了你的代码,发现了一些问题。我试过 n = 90
.
for(int x=2; x<=(n/2)*(n/2); x++)
{
next_b(&i,&j);
a[i][j]=x;
completare(i,j);
}
如果你检查这段代码,那么你可以看到 i, j
的值何时相应地变为 0, 2
然后它会转到 next_b(i, j)
方法。还有一些行试图访问 negative 索引。所以它抛出异常。
喜欢 -
else if(a[*i-2][*j]==0) // here
{
// printf("cazul 7\n");
*i+=2;
return;
}
................................................
if(*j==n-2)
{
//printf("cazul 3\n");
*i-=2;
*j=0;
return;
}
else if (a[*i-2][*j+2]!=0) // here
{
//printf("cazul 4\n");
*i+=2;
}
else if(a[*i-2][*j+2]==0) // here
{
//printf("cazul 5\n");
*i-=2;
*j+=2;
}
尝试修复这些负索引然后它应该工作(假设你的方法是正确的)。