求C语言 检查一个TXT文件 (里面是9*9个数) 是否满足数独的条件

2024-11-23 05:25:41
推荐回答(3个)
回答1:

(哥们真的写了很久,一定要给分分啊。)
(两个测试过的文件为)
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8

第二个
写的太乱了,不抄了,程序正确性应该蛮高的,在测试的时候把逻辑有弄了一遍。
你看代码的话可能第一次有点累,请耐心点看吧。
希望我的努力能对你有所帮助。

你的算法有些问题

简单来说

1*2*3*4 = 24

但是1*1*1*24 = 24;

而你的题目并没有规定数字一定是各位数,且不能重复,所以用楼主的算法在这种情况下是不成立的。
我用我的方法写一下,写好了上传

#include

int isDig(char a)
{
if(48<=a&&a<=57)
{
return 1;
}
return 0;
}

void read(FILE *txtF, int numArr[], int arrSize)
{
int digFlag, number, putFlag,i;
char c;
digFlag = 0;
putFlag = digFlag;
number = 0;
i=0;
while((c = getc(txtF))!=EOF)
{
if(isDig(c))
{
putFlag = digFlag = 1;
}
else
{
digFlag = 0;
}

if(putFlag != digFlag)
{
if(i>=arrSize)
{
break;
}
else
{
numArr[i++] = number;
}
putFlag = digFlag;
number = 0;
}

if(digFlag)
{
number = number*10+(c-48);
}

}

if(number!= 0)
numArr[i] = number;
}

int check(int arr[])
{
int a[10] = {0};
int i,j;

for(i=1; i<10; i++)
{
for(j=1; j<10; j++)
{
if(arr[i-1] == j)
{
a[j] = 1;
break;
}
}
}

for(i=1; i<10; i++)
{
if(a[i] == 0)
{
return 0;
}
}

return 1;
}

int rowCheck(int arr[])
{
int i,j,k;
int a[9];

for(i=0; i<73; i+=9)
{
for(j=i, k=0; j {
a[k] = arr[j];
}
if(!check(a))
{
printf("Row check fail at line %d\n", i+1);
return 0;
}
}

return 1;
}

int lineCheck(int arr[])
{
int i,j,k;
int a[9];

for(i=0; i<9; i++)
{
for(j=i, k=0; j<=i+72; j+=9, k++)
{
a[k] = arr[j];
}
if(!check(a))
{
printf("Line check fail at line %d\n", i+1);
return 0;
}
}
return 1;
}

int squareCheck(int arr[])
{
int i,j,h,k;
int a[9];

for(i=0; i<61; i+=3)
{
for(j=i,k=0; j {
for(h=j; h<=j+18; h+=9, k++)
{
a[k] = arr[h];
}
}
if(!check(a))
{
printf("Square check fails at the square start at %d\n", i+1);
return 0;
}
}
return 1;
}

int main(void)
{

void read(FILE*, int[], int);
int check(int[]);
int rowCheck(int[]);
int lineCheck(int[]);
int squareCheck(int[]);

FILE * fp;
int arr[81];
int i;

if((fp = fopen("data2.txt", "r"))==NULL)
{
printf("Open failed");
return 0;
}

read(fp, arr, 81);

for(i=0; i<81; i++)
{
printf("%d ",arr[i]);
if((i+1)%9 == 0 )
printf("\n");
}

fclose(fp);

printf("Row Check: %d\n", rowCheck(arr));
printf("Line Check: %d\n", lineCheck(arr));
printf("Square Check: %d\n", squareCheck(arr));
}

回答2:

我用C++写了一个,不知道你是学c的还是学C++的,不过基本东西都差不多,希望你能看懂。其实这题不用一个一个判断的,建三张hash表就可以边读入数据边判断了。且一旦检查到有不符合的情况就可以停止读入数据。至于hash表,我解释一下我程序了怎么实现的。注意,我的程序里是规定数独的行标和列表从0开始的,而不是从1开始的。hash_1[i][a]用来表示第i行值为a的情况是否被读到过,如果没被读到,其值为0,否则为一。那么,如果第i行第二次出现了a,则说明txt里的数据不是数独。hash_2[j][a]用来表示第j列,值为a的情况是否出现过。hash_3[x][a]实用来判断第x块区域内(x的值是以数独的从左到右,从上到下的顺序从0开始递增的)值为a的情况是否出现过。其中x=i/3*3+j/3;之所以要除以3再乘以三,是充分利用了除法能够取整,这个你可以自己算一下,验证一下正确性。好了,解释了这么多,希望你能看懂下面的程序,并能改编成你自己的程序。对了,如果你的软件能用bool型的话,最好将三张hash表定义成bool型,这样还能省内存
#include
#include

using namespace std;

ifstream fin("data.txt");

const int N=9;

int hash_1[N][N]={0},hash_2[N][N]={0},hash_3[N][N]={0};

int main()
{
int a,flag=0;
int i,j,x;
for(i=0; i {
for(j=0; j {
fin>>a;
if(hash_1[i][a]==1)
{
cout<<"wrong\n";
flag=1;
break;
}
hash_1[i][a]=1;

if(hash_2[j][a]==1)
{
cout<<"wrong\n";
flag=1;
break;
}
hash_2[j][a]=1;

x=i/3*3+j/3;
if(hash_3[x][a]==1)
{
cout<<"wrong\n";
flag=1;
break;
}
hash_3[x][a]=1;
}
if(flag) break;
}

if(!flag) cout<<"correct\n";
getchar(); getchar();
return 0;
}

回答3:

有一个TXT文件 里面是9*9组数
先检查每一行是否 1~9
再检查每一竖行是否满足 1~9
再检查 3*3 各自是否满足1~9

我写了一些

int rowcheck(int x[9][9], int *rowflag)
{
int i, j;
*rowflag=0;
for(j=0; j<9; j++)
{
for(i=0; i<9; i++)
{
if (x[0][j]*x[1][j]*x[2][j]*x[3][j]*x[4][j]*x[5][j]*x[6][j]*x[7][j]*x[8][j]==362880)
*rowflag=1;
else
*rowflag=0;
break;
}
}
}

int columncheck(int x[9][9], int *columnflag)
{
int i, j;
*columnflag=0;
for(i=0; i<9; i++)
{
for(j=0; j<9; j++)
{
if (x[0][j]*x[1][j]*x[2][j]*x[3][j]*x[4][j]*x[5][j]*x[6][j]*x[7][j]*x[8][j]==362880)
*columnflag=1;
else
*columnflag=0;
break;
}
}
}

int squarecheck(int x[9][9], int *squareflag)
{
int i,j;
*squareflag=0;
for(i=0;i=3;i=6)
{
for(j=0;j=3;j=6)
{if(x[i+0][j+0]*x[i+0][j+1]*x[i+0][j+2]*x[i+1][j+0]*x[i+1][j+1]*x[i+1][j+2]*x[i+2][j+0]*x[i+2][j+1]*x[i+2][j+2]==362880 && x[i+0][j+0]+x[i+0][j+1]+x[i+0][j+2]+x[i+1][j+0]+x[i+1][j+1]+x[i+1][j+2]+x[i+2][j+0]+x[i+2][j+1]+x[i+2][j+2]==45)
*squareflag=1;
else
*squareflag=0;
break;
}
}
}

这是三个检查的程序
不知道对不对 如果对麻烦谁帮我写一个MIAN的