C++/How to compare 1D arrays inside of 2D arrays to check if they are equal.
Expert: Zlatko - 6/6/2010
QuestionHello 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.
AnswerHello 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