C++/How to hold the right data into an array
Expert: Zlatko - 10/12/2010
Question
Hi Zlatko, I ran the last program you mailed me and the output is not what I want. Could you run the program I will mail
you. In this program I'm not using neither the class structure or the shiftDownOneRow() function.
Not the class structure because I'm not still familiar with it.
Not the shiftDownOneRow() function because in the program it is not working the way I want ( I'll explain you later how
I want this function works in the program).
This program has two problems:
1) The smallest total = 0;
How to output the right smallest total?
2) I added to this program the code of how to output the numbers IN and/or OUT of a matrix set for the user (you will
recognize this code because you helped me with it in the past). In this program the line 214 is not working because when
the function isInArray() is called it works with the matrix data not with the matrix into the array foundRows[]. Could you
check this program to see why this two problems happen. Thanks.
#include <iostream>
#include <iomanip>
#include <sstream>
const int rows=10;
const int columns=5;
int wishedNumber;
int rowNumber;
int columnNumber;
using namespace std;
void secondPrintHeading();
int getHighestSum( int t[], int n);
int getSmallestSum(int t[], int n);
int getWishedNumber();
void displayCombination(int [], int);
void printHeading();
bool isInArray(int number, int theArray[][columns],
int startingRow, int endingRow);
int main()
{
cout<<endl;
int smallestSum;
int highestSum;
int sumRow[rows];
memset(sumRow, 0, sizeof(sumRow));
int foundList[57];
memset(foundList, 0, sizeof(foundList));
int foundRows[rows];
memset(foundRows, 0, sizeof(foundRows));
int foundSums[rows];
memset(foundSums, 0, sizeof(foundSums));
// int* foundSums = (int*)malloc(sizeof(int)*rows);
// memset(foundSums, 0, sizeof(int)*rows);
bool foundTheNumber = false;
char choice;
int count = 0;
int counting = 0;
stringstream inMatrix;
stringstream outMatrix;
stringstream outputRow;
int sizeMatrixInOut;
int foundCount=0;
int notFoundCount=0;
int x = 0;
int y = -1;
int array[rows][columns] ={
{2, 15, 18, 20, 39},
{7, 11, 14, 15, 34},
{1, 31, 33, 34, 50},
{8, 18, 45, 47, 50},
{1, 10, 12, 32, 36},
{3, 4, 15, 27, 37},
{1, 2, 13, 19, 27},
{12, 17, 21, 23, 30},
{11, 36, 37, 41, 55},
{4, 12, 13, 21, 27 }};
printHeading();
for(int i=0; i< rows; i++)
{
cout<<setw(23)<<i<<") |";
for(int j=0; j< columns; j++)
{
cout<<setw(8)<<array[i][j];
sumRow[i]= sumRow[i] + array[i][j];
}
cout << inMatrix.str();
cout<<setw(8 - inMatrix.str().length())<<"|"; //print spaces based on remaining length
inMatrix.str(""); // clear the string stream contents.
cout<<" "<< sumRow[i]<<endl;
}
cout<<endl;
do
{
cout<<" Enter a number of row to create a matrix (rows x columns): ";
cin>>rowNumber;
do
{
cout<<" Enter a number of column (0,1,2,3 or 4) of the "
"matrix ("<< rowNumber <<" x 5): ";
cin>>columnNumber;
do
{
memset(foundList, 0, sizeof(foundList));
memset(foundRows, 0, sizeof(foundRows));
memset(foundSums, 0, sizeof(foundSums));
// memset(foundSums, 0, sizeof(int)*rows);
foundTheNumber = false;
counting = 0;
getWishedNumber();
cout<<endl<<endl;
cout<<setw(42)<<"Number "<<wishedNumber<<" in column ("<< columnNumber <<") "
"in " <<rowNumber<<" rows"<<endl;
cout<<setw(84)<<"----------------------------------------"
"---------------------\n";
printHeading();
for(int i= 0; i< rowNumber; i++)
{
if(array[i][columnNumber] == wishedNumber)
{
foundTheNumber = true;
++counting;
cout<<setw(23)<< i <<") |";
stringstream inMatrix;
displayCombination(array[i], columns);
cout << inMatrix.str();
cout<<setw(8 - inMatrix.str().length())<<"|";
inMatrix.str("");
cout<<setw(6)<< sumRow[i] <<endl;
foundSums[i] = sumRow[i];
// For the row that has the wishedNumber in the first column,
// examine all the elements in that row and record them in the foundList
for(int j = 0; j < columns; ++j)
{
foundList[array[i][j]] = 1;
}
foundRows[i] = 1;
}
}
cout<<endl;
if(foundTheNumber)
{
for(int i=0; i< rows; i++)
{
smallestSum = getSmallestSum(foundSums, i);
highestSum = getHighestSum(foundSums, i);
}
cout<<setw(62)<<"The smallest total is: "<< smallestSum<<endl;
cout<<setw(61)<<"The highest total is: "<< highestSum<<"\n\n";
stringstream outMatrix;
stringstream outputRow;
count=0;
for(int i = 1; i < 57; ++i)
{
if (foundList[i] == 0)
{
outMatrix << setw(4) << i;
// print out 15 to a line
if (++count % 15 == 0)
{
outMatrix << endl;
}
}
}
cout<<setw(39)<<"There are "<<count<<" numbers OUT of "
"the matrix ("<<counting<<" x "<<columns<<")\n";
cout<<setw(84)<<"----------------------------------------"
"---------------------\n";
if(count <= 15)
{
outputRow <<setw(168)<< outMatrix.str()<<endl;
cout << outputRow.str() << endl;
}
else
{
cout<<endl;
outputRow << outMatrix.str() <<endl;
cout << outputRow.str() << endl;
}
// This is the new code
do
{
cout<<" Enter the size of the matrix to analize: ";
cin>>sizeMatrixInOut;
cout<<endl;
cout<<setw(82)<<" Frecuency's numbers of a row IN and/or OUT "
"of a matrix of size ( "<<sizeMatrixInOut<<" x "
<<columns<<" )\n";
secondPrintHeading();
for(int i = 0; i< sizeMatrixInOut; ++i)
{
if(foundRows[i] == 1)
{
cout<<setw(5)<< i <<") |";
for(int j = 0; j< columns; ++j)
{
cout<<setw(6) << array[i][j];
}
stringstream inMatrix;
stringstream outMatrix;
stringstream outputRow;
//
// analyze the row
//
foundCount=0;
notFoundCount=0;
x++;
y++;
for(int j=0; j< columns; j++)
{
// Remember, rows is the count of the number of rows
// the last valid row index is rows-1, because indexes start at 0
if (isInArray(array[i][j], array,
rowNumber - sizeMatrixInOut - y, rowNumber-x))
{
foundCount++;
inMatrix <<setw(3)<< array[i][j];
}
else
{
notFoundCount++;
outMatrix <<setw(3)<< array[i][j];
}
}
outputRow << " | " << inMatrix.str();
// The first "|" will be at column 29
outputRow << setw(29-outputRow.str().length()) << " | " << outMatrix.str();
// The second "|" will be at column 48
outputRow << setw(48-outputRow.str().length()) << " | " << setw(3) << foundCount;
outputRow << " | " << setw(3) << notFoundCount;
cout << outputRow.str() << endl;
}
}
//
// print out the rest of the rows
//
for(int i = sizeMatrixInOut; i< rowNumber; i++)
{
if(foundRows[i] == 1)
{
cout<<setw(5)<< i <<") |";
for(int j=0; j<columns; j++)
{
cout<<setw(6)<<array[i][j];
}
cout<<endl;
}
}
cout<<"\n\n Would you like to look up another "
"size of a matrix to see numbers IN and/or OUT of it? (y/n): ";
cin >> choice;
} while (choice == 'y'|| choice == 'Y');
}
// End of the new code
if (! foundTheNumber)
{
cout<<setw(42)<<"NUMBER " << wishedNumber << " is not in the "
"column ("<< columnNumber <<")\n\n";
}
cout<<" Would you like to look up another "
"number in column ("<< columnNumber <<") (y/n)? : ";
cin >> choice;
} while (choice == 'y'|| choice == 'Y');
cout<<" Would you like to look up another column (y/n)? : ";
cin >> choice;
} while (choice == 'y'|| choice == 'Y');
cout<<" Would you like to analized another size of a matrix (y/n)? : ";
cin >> choice;
} while (choice == 'y'|| choice == 'Y');
cout<<endl;
return 0;
}
void printHeading()
{
cout<<endl;
cout<<setw(84)<<" Rows (0) (1) (2) (3) (4) Sums\n";
cout<<setw(92)<<"------------------------------------------------"
"-----------------------------\n";
}
void displayCombination(int array[], int columns)
{
for( int i=0; i < columns; i++)
{
cout << setw(8) << array[i];
}
}
int getHighestSum( int t[], int n)
{
int highest = t[0];
for(int i = 1; i < n; i++)
if ( t[i] > highest)
highest = t[i];
return highest;
}
int getSmallestSum(int t[], int n)
{
int smallest = t[0];
for(int i = 1; i < n; i++)
if ( t[i] < smallest)
smallest = t[i];
return smallest;
}
int getWishedNumber()
{
int minWishedNumber = 1;
int maxWishedNumber = 56;
cout<<" Enter the number you are searching for in column "
"("<<columnNumber<<") of the matrix ("<<rowNumber<<" x 5): ";
cin >> wishedNumber;
while (wishedNumber < minWishedNumber || wishedNumber > maxWishedNumber)
{
cout<<"\n I'm sorry, enter a number in the range of " << minWishedNumber;
cout <<" through " << maxWishedNumber << ": ";
cin >> wishedNumber;
cout<<endl;
}
return wishedNumber;
}
bool isInArray(int number, int theArray[][columns],
int startingRow, int endingRow)
{
for(int row = startingRow; row <= endingRow; ++row)
{
for(int col = 0; col < columns; ++col)
{
if (theArray[row][col] == number) return true;
}
}
return false;
}
void secondPrintHeading()
{
cout<<" -----------------------------------------"
"----------------------------------------------------------\n\n";
cout<<setw(104)<<" Matrix's Numbers Total Matrix's Numbers\n";
cout<<" ROWS (0) (1) (2) (3) (4) IN OUT IN OUT\n";
cout<<" -----------------------------------------"
"----------------------------------------------------------\n";
}
AnswerHi Raul.
I assume you want the smallest and largest sum of only the rows that have your wishedNumber because your foundSums[X] is initialized only when wishedNumber is found. For rows that don't have the wishedNumber, foundSums[X] remains 0. Then when scanning foundSums, the 0 is picked up as the minimum. To fix it, you must pass foundRows to getSmallestSum and examine foundSums[X] only if foundRows[X] != 0
Also you don't need to loop like this
for(int i=0; i< rows; i++)
{
smallestSum = getSmallestSum(foundSums, i);
highestSum = getHighestSum(foundSums, i);
}
because the getSmallestSum and getHighestSim has its own loop.
Do like this:
// Declaration
int getHighestSum( int t[], int found[], int n);
int getSmallestSum( int t[], int found[], int n);
// Call
if(foundTheNumber)
{
smallestSum = getSmallestSum(foundSums, foundRows, rows);
highestSum = getHighestSum(foundSums, foundRows, rows);
cout<<setw(62)<<"The smallest total is: "<< smallestSum<<endl;
cout<<setw(61)<<"The highest total is: "<< highestSum<<"\n\n";
//Definition
And define the functions like this:
int getHighestSum( int t[], int found[], int n)
{
int highest = INT_MIN;
for(int i = 0; i < n; i++)
if ( found[i] && t[i] > highest)
highest = t[i];
return highest;
}
int getSmallestSum(int t[], int found[], int n)
{
int smallest = INT_MAX;
for(int i = 0; i < n; i++)
if ( found[i] && t[i] < smallest)
smallest = t[i];
return smallest;
}
include <limits.h> if your compiler complains about INT_MAX and INT_MIN.
Run your program with inputs 7 0 1
You should get smallest is 62, largest is 149
Your second problem is occurring in the new code
// This is the new code
do
{
cout<<" Enter the size of the matrix to analize: ";
cin>>sizeMatrixInOut;
cout<<endl;
cout<<setw(82)<<" Frecuency's numbers of a row IN and/or OUT "
"of a matrix of size ( "<<sizeMatrixInOut<<" x "
<<columns<<" )\n";
secondPrintHeading();
for(int i = 0; i< sizeMatrixInOut; ++i)
{
if(foundRows[i] == 1)
The last line I pasted shows that the isInArray is called only when foundRows[i] is non zero. It may be that all foundRows[0 to sizeMatrixInOut are 0, so isInArray is never even called.
It is time for you to learn how to use a debugger and step through your code. That is a critical step to learning how to program. Try to watch some videos, or read about your debugger at
http://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks
I think you are using code blocks. Is that right ? Use google to search for videos.
Also, try putting these lines
if (startingRow < 0) cout << "Error: startingRow < 0\n";
if (endingRow < 0) cout << "Error: endingRow < 0\n";
if (endingRow < startingRow) cout << "Error: endingRow < startingRow < 0\n";
into the start of your isInArray function. It may give you some clues.