nischalinn
nischalinn

Reputation: 1175

check for equal matrix using function

I am trying to check whether two matrix are equal via function. But I am confused how to write argument for the function EqualMatrices. Since the logic is to compare equality or rows and columns how to pass such array in function argument.

#include <stdio.h> 
    
    void EqualMatrices(int A[][10], int B[][10]) // how to write arguments for this function
    {
        /*  Comparing two matrices for equality: this is the logic */ 

        if (row1 == row2 && column1 == column2)

        {

            printf("Matrices can be compared \n");

            for (i = 0; i < row1; i++) 

            {

                for (j = 0; j < column2; j++)

                {

                    if (a[i][j] != b[i][j])

                    {

                        flag = 0;

                        break;

                    }

                 }

            }

        }

        else 

        {

            printf(" Cannot be compared\n");

            exit(1);

        }

 

        if (flag == 1)

            printf("Two matrices are equal \n");

        else

            printf("But, two matrices are not equal \n");
    }

void main() 
    { 

        int a[10][10], b[10][10];

        int i, j, row1, column1, row2, column2, flag = 1;

 

        printf("Enter the order of the matrix A \n");

        scanf("%d %d", &row1, &column1);
 

        printf("Enter the order of the matrix B \n");

        scanf("%d %d", &row2, &column2);
        
        
            printf("Enter the elements of matrix a \n");

            for (i = 0; i < row1; i++)
    
            {
    
                for (j = 0; j < column1; j++) 
    
                {
    
                    scanf("%d", &a[i][j]);
    
                }
    
            }

        printf("Enter the elements of matrix b \n");

        for (i = 0; i < row2; i++) 

        {

            for (j = 0; j < column2; j++)

            {

                scanf("%d", &b[i][j]);

            }

        }

 

        printf("MATRIX a is \n");

        for (i = 0; i < row1; i++)

        {

            for (j = 0; j < column1; j++) 

            {

                printf("%d", a[i][j]);

            }

            printf("\n");

        }

 

        printf("MATRIX b is \n");

        for (i = 0; i < row2; i++)

        {

            for (j = 0; j < column2; j++) 

            {

                printf("%d", b[i][j]);

            }

            printf("\n");

 

        }
        
        EqualMatrices(a, b);

        return 0; 

    }

Upvotes: 0

Views: 511

Answers (2)

user4221591
user4221591

Reputation: 2180

Hope this will work. I have done this without using pointer.

 #include <stdio.h> 
    
    void EqualMatrices(int A[][10], int B[][10], int row1, int column1, int row2, int column2)
    {
        /*  Comparing two matrices for equality */ 
        int i,j, flag = 1;

        if (row1 == row2 && column1 == column2)
        {
            printf("Matrices can be compared \n");
            for (i = 0; i < row1; i++) 
            {
                for (j = 0; j < column2; j++)
                {
                    if (A[i][j] != B[i][j])
                    {
                        flag = 0;
                        break;
                    }
                 }
            }
        }
        else 
        {
            printf("\n Cannot be compared\n");
            exit(1);
        }
        if (flag == 1)
        {
            printf("\n Two matrices are equal \n");
        }
        else
        {
            printf("\n Two matrices are not equal \n");
        }   
    }

    int main() 
    { 
        int a[10][10], b[10][10];
        int i, j, row1, column1, row2, column2;
        
        printf ("Enter the order of the matrix A (mxn):\n");
        printf ("Row of matrix (mxn): ");
        scanf ("%d", &row1);
        printf ("Column of matrix (mxn): ");
        scanf ("%d", &column1);
        
        printf ("Enter the order of the matrix B (mxn):\n");
        printf ("Row of matrix (mxn): ");
        scanf ("%d", &row2);
        printf ("Column of matrix (mxn): ");
        scanf ("%d", &column2);

        
            printf("Enter the elements of matrix a \n");

            for (i = 0; i < row1; i++)  
            {   
                for (j = 0; j < column1; j++)   
                {
                    printf("Enter a[%d][%d]: ",i,j);    
                    scanf("%d", &a[i][j]);  
                }   
            }

        printf("Enter the elements of matrix b \n");

        for (i = 0; i < row2; i++)
        {
            for (j = 0; j < column2; j++)
            {
                printf("Enter b[%d][%d]: ",i,j);    
                scanf("%d", &b[i][j]);
            }
        }
        printf("\n MATRIX a is \n");
        
        for (i = 0; i < row1; i++)
        {
            printf("\n");
            for (j = 0; j < column1; j++) 
            {
                printf("%d\t", a[i][j]);
            }
        }

        printf("\n MATRIX b is \n");
        
        for (i = 0; i < row2; i++)
        {
            printf("\n");
            for (j = 0; j < column2; j++) 
            {
                printf("%d\t", b[i][j]);
            }
            printf("\n");
        }
        
        EqualMatrices(a, b, row1, column1, row2, column2);
        
        return 0; 
    }

Upvotes: 1

rel
rel

Reputation: 794

The question is related to more general ones that have been answered there: How are multi-dimensional arrays formatted in memory? / How to pass a 2D array by pointer in C?

Here, an attempt to create simple matrix comparison functions, that illustrate how plain arrays can be used directly:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

/* VARIANT 0: compare elements of arrays in a nested loop
   -> no obvious advantages over VARIANT 1 */
bool matrix_equal0(
    const int *a, const int *b, unsigned int rows, unsigned int columns)
{
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < columns; j++) {
            if (a[i * columns + j] != b[i * columns + j]) {
                return false;
            }
         }
    }
    return true;
}

/* VARIANT 1: compare elements of matrices one by one,
   simpler and more performant than VARIANT 0 */
bool matrix_equal1(
    const int *a, const int *b, unsigned int rows, unsigned int columns)
{
    unsigned int i = rows * columns;
    while (i--) {
        if (*a++ != *b++) {
            return false;
        }
    }
    return true;
}

/* VARIANT 2:
   compare both arrays as a chunk of memory (possible but not recommended) */
bool matrix_equal2(
    const int *a, const int *b, unsigned int rows, unsigned int columns)
{
    return (memcmp(a, b, rows * columns * sizeof(int)) == 0);
}

int main(void)
{
    const int mat0[3][3] = {
        { 1, 2, 3, },
        { 4, 5, 6, },
        { 7, 8, 9, },
    };
    const int mat1[3][3] = {
        { 1, 2, 3, },
        { 4, 5, 6, },
        { 7, 8, 9, },
    };
    const int mat2[3][3] = {
        { 1, 2, 3, },
        { 4, 5, 6, },
        { 7, 8, 9999, },
    };
    if (matrix_equal0(&mat0[0][0], &mat1[0][0], 3, 3)) {
        printf("VARIANT 0: mat0 and mat1 are equal!\n");
    }
    if (matrix_equal0(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
        printf("VARIANT 0: mat0 and mat2 are NOT equal!\n");
    }

    if (matrix_equal1(&mat0[0][0], &mat1[0][0], 3, 3)) {
        printf("VARIANT 1: mat0 and mat1 are equal!\n");
    }
    if (matrix_equal1(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
        printf("VARIANT 1: mat0 and mat2 are NOT equal!\n");
    }

    if (matrix_equal2(&mat0[0][0], &mat1[0][0], 3, 3)) {
        printf("VARIANT 2: mat0 and mat1 are equal!\n");
    }
    if (matrix_equal2(&mat0[0][0], &mat2[0][0], 3, 3) == false) {
        printf("VARIANT 2: mat0 and mat2 are NOT equal!\n");
    }
    return 0;
}

Output:

VARIANT 0: mat0 and mat1 are equal!
VARIANT 0: mat0 and mat2 are NOT equal!
VARIANT 1: mat0 and mat1 are equal!
VARIANT 1: mat0 and mat2 are NOT equal!
VARIANT 2: mat0 and mat1 are equal!
VARIANT 2: mat0 and mat2 are NOT equal!

NOTE: Caution should be taken when 2D matrices are treated as plain arrays. How the columns and rows relate to the 1D memory layout of the array can be a source of confusion and cause bugs. - Here a quick example, that illustrates the relationship:

#include <stdio.h>

/* print the elements of a 2D matrix */
void matrix_print(const int *mat, unsigned int rows, unsigned int columns)
{
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < columns; j++) {
            printf("%d ", mat[i * columns + j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main(void)
{
    const int mat[2][3] = {
        { 1, 2, 3, },
        { 4, 5, 6, },
    };
    matrix_print(&mat[0][0], 2, 3);
    return 0;
}

Output:

1 2 3 
4 5 6 

If your project requires lots of matrix math, it might make sense to use a custom type to make them easier to handle and to build up a library-esque set of utility functions. - Here an example that illustrates how a compare function might look like in that case:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

/* VARIANT 3: instead of using a 2D array to represent a matrix, 
              a custom type is used. That makes it easier/nicer to pass
              matrices around various places in your code. */
typedef struct {
    unsigned int rows;
    unsigned int columns;
    int *elements;
} matrix;

matrix matrix_new(unsigned int rows, unsigned int columns)
{
    matrix mat;
    mat.rows = rows;
    mat.columns = columns;
    mat.elements = calloc(rows * columns, sizeof(int)); /* zero matrix */
    return mat;
}

bool matrix_clear(matrix *mat)
{
    if (mat == NULL)
        return false;
    mat->rows = 0;
    mat->columns = 0;
    free(mat->elements);
    mat->elements = NULL;
    return true;
}

bool matrix_elem(matrix *mat, unsigned int row, unsigned int column, int val)
{
    if (mat == NULL)
        return false;
    if (row >= mat->rows || column >= mat->columns)
        return false;
    if (mat->elements == NULL)
        return false;
    mat->elements[row * mat->columns + column] = val;
    return true;
}

bool matrix_compare(const matrix *mat0, const matrix *mat1)
{
    if (mat0 == NULL || mat1 == NULL)
        return false;
    if (mat0->rows != mat1->rows)
        return false;
    if (mat0->columns != mat1->columns)
        return false;
    int *a = mat0->elements;
    int *b = mat1->elements;
    unsigned int i = mat0->rows * mat0->columns;
    while (i--) {
        if (*a++ != *b++) {
            return false;
        }
    }
    return true;
}

int main(void)
{
    matrix mat3 = matrix_new(3, 3);
    matrix mat4 = matrix_new(3, 3);
    matrix mat5 = matrix_new(3, 3);
    matrix_elem(&mat3, 1, 1, 12);
    matrix_elem(&mat4, 1, 1, 12);
    matrix_elem(&mat5, 1, 1, 13);
    //matrix_copy_from_2d_array(&mat6, mat0); // todo
    if (matrix_compare(&mat3, &mat4)) {
        printf("VARIANT 3: mat3 and mat4 are equal!\n");
    }
    if (matrix_compare(&mat3, &mat5) == false) {
        printf("VARIANT 3: mat3 and mat5 are NOT equal!\n");
    }
    matrix_clear(&mat3);
    matrix_clear(&mat4);
    matrix_clear(&mat5);
    
    return 0;
}

Output:

VARIANT 3: mat3 and mat4 are equal!
VARIANT 3: mat3 and mat5 are NOT equal!

Upvotes: 0

Related Questions