You are here:

C++/How to compare 1D arrays inside of 2D arrays to check if they are equal.

Advertisement


Question
Hello Zlatko.
   I did what told me:

   bool comparison;
   for(int i=0; i< rows; i++)
     {
       for(int j=i+1; j<rows; j++)
          comparison = MyCompare(array[i], array[j], 5);

     but still there is something wrong because in the data when a row is repeated  three times the program displays this row  but at same time  when a row is repeated  two times the program do not displays that row . I am thinking  because exist  three case to display:

  1) When in the 2D array all rows are equal.
  2) When in the 2D array all rows are different.
  3) When exist both cases at same time(equal rows and different rows)
 
  Do you think this has to do with the output of the program?
  Could you check the program again, may be you can find another error. THANKS again.

Answer
Hello Raul.
I think the program is working, but the display may not be what you want. Below is the original program with the logic changes I suggested, plus 1 more. My logic changes have comments starting with ZM. Below that is the output. I changed the output a little to make it more clear to me.

Program:
=========================================================

#include <iostream>
#include <iomanip>

using namespace std;

const int rows = 9;
const int cols = 5;

bool MyCompare(int*, int*, int);
void displayrowMatch(int[], int);

int main()
{
   cout<<endl;
   int array[rows][cols] = {{1,4,4,7,8},
   {2,4,4,7,8},
   {1,4,4,7,8},
   {3,4,4,7,8},
   {5,4,4,7,8},
   {3,4,4,7,8},
   {5,4,4,7,8},
   {3,4,4,7,8},
   {2,4,4,7,8}};
   bool comparison = false; // ZM changed to bool
   for(int i=0; i< rows; i++)
   {
       cout << i << ") ";
       for(int j=0; j< cols; j++)
       {
           cout<<setw(7)<<array[i][j];
       }
       cout<<endl;
   }
   cout<<endl;
   for(int i=0; i< rows; i++)
   {
       for(int j=i+1; j<rows; j++)
       {
           /*
               ZM i am changing the use of the  comparison flag. If there are any matches, the
               comparison flag is set to prevent the "no match" message.
           */
           if(MyCompare(array[i], array[j], 5) == true) // ZM changed i+1 to j
           {
               comparison =  true; // ZM if **any** matches, dont print the no match message below.
               cout << "Matched " << i << " and " << j << endl;
               //displayrowMatch(array[i], 5);
           }

       }
   }
   if(comparison == false)
   {
       cout<<"   It does not exist equals rows "<<endl;
   }
   cout<<endl;
   return 0;
}

bool MyCompare(int* first, int* second, int numelements)
{
   bool rowMatch=true;

   for(int i=0; i<numelements; i++)
   {
       for(int j=i+1; j<numelements; j++)
       {
           for(int k=0; k<numelements && rowMatch;k++)
           {
               if(first[i]!=second[i]) // ZM removed semicolon
                   return  false;
           }
       }
   }
   return true;
}

void displayrowMatch(int lineMatch[], int elements)
{
   for(int i=0; i < elements; i++)
   {
       cout<<setw(7)<<lineMatch[i];
   }
   cout<<endl;
}

Output:
=========================================================

0)       1      4      4      7      8
1)       2      4      4      7      8
2)       1      4      4      7      8
3)       3      4      4      7      8
4)       5      4      4      7      8
5)       3      4      4      7      8
6)       5      4      4      7      8
7)       3      4      4      7      8
8)       2      4      4      7      8

Matched 0 and 2
Matched 1 and 8
Matched 3 and 5
Matched 3 and 7
Matched 4 and 6
Matched 5 and 7

Clearly when there are 2 copies of a row, the matches are printed. See row 0 and 2.

For 3 matches the output is a little misleading. You see row 3 matches 5, and 3 matches 7, but later when row 5 is examined, it is compared only against 7, so there is no printout about 5 matching 3.

What you probably want is output like this:


0)       1      4      4      7      8
1)       2      4      4      7      8
2)       1      4      4      7      8
3)       3      4      4      7      8
4)       5      4      4      7      8
5)       3      4      4      7      8
6)       5      4      4      7      8
7)       3      4      4      7      8
8)       2      4      4      7      8

Matched 0,2
Matched 1,8
Matched 3,5,7
Matched 4,6

For that, you need to add an array to flag which rows have been reported. If a row has already been reported as matching another row, then it is not compared ever again. For example, row 3 matches 5, and 7 so that is printed, but when it is time to examine row 5, it has already been put into a match set, so it is not necessary to check what 5 matches. The code for that is below.

int main()
{
   cout<<endl;
   int array[rows][cols] = {{1,4,4,7,8},
   {2,4,4,7,8},
   {1,4,4,7,8},
   {3,4,4,7,8},
   {5,4,4,7,8},
   {3,4,4,7,8},
   {5,4,4,7,8},
   {3,4,4,7,8},
   {2,4,4,7,8}};

   // ZM added reported array
   bool reported[rows];
   memset(reported, 0, sizeof(reported));

   bool comparison = false; // ZM changed to bool
   for(int i=0; i< rows; i++)
   {
       cout << i << ") ";
       for(int j=0; j< cols; j++)
       {
           cout<<setw(7)<<array[i][j];
       }
       cout<<endl;
   }
   cout<<endl;
   for(int i=0; i< rows; i++)
   {
       if (! reported[i])
       {
           for(int j=i+1; j<rows; j++)
           {
               /*
               ZM i am changing the use of the  comparison flag. If there are any matches, the
               comparison flag is set to prevent the "no match" message.
               */
               if(MyCompare(array[i], array[j], 5) == true) // ZM changed i+1 to j
               {
                   comparison =  true; // ZM if **any** matches, dont print the no match message below.

                   if (! reported[i]) cout << "Matched " << i;
                   cout << ',' << j;
                   //displayrowMatch(array[i], 5);
                   reported[i] = true;
                   reported[j] = true;
               }
           }
           if (reported[i]) cout << endl;
       }
   }
   if(comparison == false)
   {
       cout<<"   It does not exist equals rows "<<endl;
   }
   cout<<endl;
   return 0;
}

Have a look at how the reported array is used. Does it make sense to you?

Best regards
Zlatko

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2012 About.com, a part of The New York Times Company. All rights reserved.