I wrote a program to check wether a square n*n
matrix is "perfect", meaning each line and row hold exactly one instance of each number from 1 to n
.
I also wrote a main function to allocate memory for a given size and receive values of that matrix from the user.
It seems to work fine, except when I chose 4 for size and input this matrix: {{1,2,3,4},{2,1,4,3},{3,4,2,1),{4,3,1,2}}
.
I get the matrix {{1,2,3,4},{2,**3**,4,3},{3,4,**3**,1},{4,3,1,2}}
.
It looks like an input thing, but I can t find what
s wrong :(
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int IsPerfect(int *arr, int size);
void main() {
int size = 0, i = 0, j = 0, vol = 0;
printf("please enter matrix size, 0 to exit:\n");
scanf("%d", &size);
printf("size is :%d\n", size);
while (size != 0) { //loop for allocating and inputing ,matrix
int *pmatrix = (int *)malloc(size*size * sizeof(int));
printf("please input matrix:\n");
for (i = 0; i < size; i++)
for (j = 0; j < size; j++) {
printf("[%d][%d]\n", i, j);
scanf("%d", ((pmatrix + i) + j)); //storing matrix values
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++)
printf("[%d]", *((pmatrix + i) + j)); //printing matrix
printf("\n");
}
IsPerfect(pmatrix, size); //perfect check
free(pmatrix);
printf("please enter matrix size, 0 to exit:\n");
scanf("%d", &size);
}
printf("bye bye!\n");
}
int IsPerfect(int *arr, int size) {
int i = 0, j = 0, w = 0, perf = 1;
int *check = (int *)malloc(sizeof(int) * size);
for (w = 0; w < size; w++) { //horizontal check
for (i = 0; i < size; i++)
*(check + i) = 0;
for (i = 0; i < size; i++)
for (j = 1; j <= size; j++)
if (*((arr + w) + i) == j)
*(check + j - 1) = *(check + j - 1) + 1;
for (i = 0; i < size; i++)
if (*(check + i) == 0 || *(check + i) > 1)
perf = 0;
}
for (w = 0; w < size; w++) { //vertical check
for (i = 0; i < size; i++)
*(check + i) = 0;
for (i = 0; i < size; i++)
for (j = 1; j <= size; j++)
if (*((arr + i) + w) == j)
*(check + j - 1) = *(check + j - 1) + 1;
for (i = 0; i < size; i++)
if (*(check + i) == 0 || *(check + i) > 1)
perf = 0;
}
if (perf == 1)
printf("the matrix is perfect\n");
if (perf == 0)
printf("the matrix is not perfect\n");
free(check);
return perf;
}
the following proposed code:
size_t
for the index types as those values should never be less than 0 and better matches the expectations of the malloc()
functionfor ( size_t col = 1; col <= size; col++ )
to limit the scope
of local variables to the enclosing for()
loop bodycheck()
function, where, again, the method of accessing the matrix elements is not correctcheck()
function is the addressing of the elements of the array i
and j
for better understanding. i ==> row
and j ==> col
Note: this statement is typical of the problems in the code:
if ( *(check + row) == 0 || *(check + row) > 1 )
because check
is at [0][0] so when adding row
that is indexing across the first row IE [0][0]...[0][3]. Not what the code needs to do to check a column of the matrix
Perhaps you meant:
if ( *(check + size*row + col) == 0 || *(check + size*row + col) > 1 )
which would index [0][col]... [3][col]
And now, the proposed code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int IsPerfect( int *arr, size_t size );
int main( void )
{
size_t size;
printf("please enter matrix size, 0 to exit:\n");
scanf("%zu", &size);
printf("size is :%zu\n", size);
while ( size != 0 )
{ //loop for allocating and inputing ,matrix
int *pmatrix = malloc( size*size * sizeof(int) );
if( ! pmatrix )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
printf( "please input matrix:\n" );
for ( size_t row = 0; row < size; row++)
{
for ( size_t col = 0; col < size; col++)
{
printf( "[%zu][%zu]\n", row, col );
if( scanf( "%d", &pmatrix[ (size*row) + col ]) != 1 ) //storing matrix values row by row
{
fprintf( stderr, "scanf for matrix entry failed\n" );
free( pmatrix );
exit( EXIT_FAILURE );
}
}
}
for ( size_t row = 0; row < size; row++)
{
for ( size_t col = 0; col < size; col++)
{
printf( "[%d]", pmatrix[ row*size + col ] ); //printing matrix
}
printf( "\n" );
}
IsPerfect( pmatrix, size ); //perfect check
free( pmatrix );
printf( "please enter matrix size, 0 to exit:\n" );
scanf( "%zu", &size );
}
printf( "bye bye!\n" );
}
int IsPerfect( int *arr, size_t size )
{
int perf = 1;
int *check = malloc( sizeof(int) * size );
if( !check )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
for ( size_t w = 0; w < size; w++ )
{ //horizontal check
for ( size_t row = 0; row < size; row++ )
{
*(check + row) = 0;
}
for ( size_t row = 0; row < size; row++ )
{
for ( size_t col = 1; col <= size; col++ )
{
if ( *((arr + w) + row) == (int)col )
{
*(check + col - 1) = *(check + col - 1) + 1;
}
}
}
for ( size_t row = 0; row < size; row++ )
{
if ( *(check + size*row) == 0 || *(check + size*row) > 1 )
{
perf = 0;
}
}
}
for ( size_t w = 0; w < size; w++ )
{ //vertical check
for ( size_t row = 0; row < size; row++ )
{
*(check + size*row) = 0;
}
for ( size_t w = 0; w < size; w++ )
{
for ( size_t col = 1; col <= size; col++ )
{
// why expect a position reference in the matrix to be the same as the content
if ( *((arr + size*col) + w) == (int)col )
{
*(check + col - 1) = *(check + col - 1) + 1; // causes seg fault
}
}
}
for ( size_t row = 0; row < size; row++ )
{
if ( *(check + row) == 0 || *(check + row) > 1 )
{
perf = 0;
}
}
}
if (perf == 1)
{
printf( "the matrix is perfect\n" );
}
else
{
printf( "the matrix is not perfect\n" );
}
free( check );
return perf;
}
Note: a run of the proposed code and using the OPs data, results in:
[1][2][3][4]
[2][1][4][3]
[3][4][2][1]
[4][3][1][2]
so the input operation is now correct, but the check()
function is still way off (and results in a seg fault event on (approx) line number 109:
if ( *((arr + size*col) + w) == (int)col )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.