How to compare the value inside of an array - c++

So Im writing a program that asks the user to input the number of pancakes a person(1-10) had for breakfast. The program must analyze the input and determine which person ate the most pancakes. Also the program must output a list in order of number of pancakes eaten of all 10 people. So far I have written the code to get the user input and the code to display the array, but not in order. Im completely lost when it comes to comparing the elements in the array:
int getPancakes();
void displayArray(int theArray[],int sizeOfArray);
void compareArray(int sizeOfArray);
int pancakes[10];
int z = 0;
int main()
{
}
int getPancakes(){
int y;
int x = 0;
for(int y = 0; y < 10; y++){
++x;
cout << "How many pancakes did person " << x << " eat?" << endl;
cin >> pancakes[y];
}
}
void displayArray(int theArray[],int sizeOfArray){
for(int x = 0 ;x < sizeOfArray ; x++){
++z;
cout << "Person " << z << " ate " << pancakes[x] << " pancakes" << endl;
}
}
So how can I instruct my program to compare the elements inside the array? Also how can I instruct my program to print the list of number of pancakes eaten by each person in order?

In order to find who ate the most pancakes, you basically need to find the position of the maximum value in the array.
int findMaxPosition(int array[], int arraySize){
int maxPosition = 0; //assume the first element is maximum
for(int i = 1; i < arraySize; i++)
if(array[i] > array[maxPosition]) //compare the current element with the known max
maxPosition = i; //update maxPosition
return maxPosition;
}
Note that this gives you the first occurence of the maximum value. If the elements are unique, that's enugh. Otherwise, you should find the maximum value, array[maxPosition], and iterate through the array and display every position on which it occurs.
Sorting is a little bit complicated. The sorting algorithms aren't so straightforward, and I'm afraid that if I write you an implementation, I wouldn't help you.
One of the simplest sorting algorithms is bubble sort. Wikipedia (http://en.wikipedia.org/wiki/Bubble_sort) has a detailed page about it, and you should be able to implement it using the pseudocode given there.

If all numbers are unique
int max = 0;
for(int x = 0 ;x < 10 ; x++)
{
if(pancakes[x] > max)
max = pancakes[x];
}
for(int x = 0 ;x < 10 ; x++)
{
if(pancakes[x] == max)
cout << "Person " << x << " ate " << pancakes[x] << " pancakes - biggest number" << endl;
}

To be blunt, there are two methods for comparing an element of an array to another value, direct and through a copy.
// Make a copy:
int count = pancakes[x];
if (count == limit)
{
//...
}
// Direct access
if (pancakes[x] == limit)
{
//...
}

There is no need to run through the array looking for max then sorting to provide output. Instead, you can just keep track of the max value you have found during the input phase:
int getPancakes(){
int max = 0;
for(int y = 0; y < 10; y++){
cout << "How many pancakes did person " << y << " eat?" << endl;
cin >> pancakes[y];
if (pancakes[y]>pancakes[max]){
max = y;
}
}
return max;
}
Note that I removed the redundant declaration of y (you are declaring it in the for loop) and x (was always going to be equal to y).
I also added a return to the function (index of the person who has eaten the most) as you had no return value. (Either return something or make the function return void (no return)).
If you only care about the max number eaten, then you don't even need to keep track of max. Instead, just read the largest value from the array after the sorting step.
Now all you need to do is implement void sortArray() and call it before calling the display function:
int main()
{
int max = getPancakes();
sortArray(); //left to you to implement
displayArray(pancakes,10);
}
You may want to consider making pancakes local to main and passing it into your functions in the same way that you are doing displayArray.

I just finished coming up with a solution to the same exercise, regarding the "who ate the most" part, even if there is more than one person who ate the most pancakes. It involves arrays and vectors. Tested and working:
#include <iostream>
#include <array>
#include <vector>
using namespace std;
int main()
{
array <int, 10> PancakeEater;
vector<int> Winners;
int max;
cout << "Type number of pancakes eaten, separated by spaces, for each of the ten contestants:" << endl;
cout << "#1 #2 #3 #4 #5 #6 #7 #8 #9 #10" << endl;
for (int i = 0; i < PancakeEater.size(); i++)
{
cin >> PancakeEater[i];
}
max = PancakeEater[0];
Winners.push_back(1);
for (int i = 0; i < PancakeEater.size()-1; i++)
{
if (max == PancakeEater[i + 1])
{
Winners.push_back(i + 2);
}
if (max < PancakeEater[i + 1])
{
max = PancakeEater[i + 1];
Winners.clear();
Winners.shrink_to_fit();
Winners.push_back(i + 2);
}
}
if (Winners.size() > 1)
{
cout << endl << "The contestants that ate the most pancakes, on a tie for first place, are contestant numbers " << endl;
for (auto item : Winners)
{
cout << item << " ";
}
}
else
{
cout << endl << "The contestant that ate the most pancakes is contestant number " << endl;
for (auto item : Winners)
{
cout << item << " ";
}
}
}

Related

How would you go about resolving this output value?

I finished this code homework assignment tonight. I thought I was done, but I just realized that my "Average" value is coming out wrong with certain values. For example: When my professor entered the values 22, 66, 45.1, and 88 he got an "Average" of 55.27. However, when I enter those values in my program, I get an "Average" of 55.25. I have no idea what I am doing wrong. I was pretty confident in my program until I noticed that flaw. My program is due at midnight, so I am clueless on how to fix it. Any tips will be greatly appreciated!
Code Prompt: "Write a program that dynamically allocates an array large enough to hold a user-defined number of test scores. Once all the scores are entered, the array should be passed to a function that sorts them in ascending order. Another function should be called that calculates the average score. The program should display the sorted list of scores and averages with appropriate headings. Use pointer notation rather than array notation whenever possible."
Professor Notes: The book only states, "Input Validation: Do not accept negative numbers for test scores." We also need to have input validation for the number of scores. If it is negative, including 0, the program halts, we should consider this situation for 'counter' not to be negative while we have a loop to enter numbers. So negative numbers should be rejected for the number of scores and the values of scores.
Here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
void showArray(double* array, int size);
double averageArray(double* array, int size);
void orderArray(double* array, int size);
int main()
{
double* scores = nullptr;
int counter;
double numberOfScores;
cout << "\nHow many test scores will you enter? ";
cin >> numberOfScores;
if (numberOfScores < 0) {
cout << "The number cannot be negative.\n"
<< "Enter another number: ";
cin >> numberOfScores;
}
if (numberOfScores == 0) {
cout << "You must enter a number greater than zero.\n"
<< "Enter another number: ";
cin >> numberOfScores;
}
scores = new double[numberOfScores];
for (counter = 0; counter < numberOfScores; counter++) {
cout << "Enter test score " << (counter + 1) << ": ";
cin >> *(scores + counter);
if (*(scores + counter) < 0) {
cout << "Negative scores are not allowed. " << endl
<< "Enter another score for this test : ";
cin >> *(scores + counter);
}
}
orderArray(scores, counter);
cout << "\nThe test scores in ascending order, and their average, are: " << endl
<< endl;
cout << " Score" << endl;
cout << " -----" << endl
<< endl;
showArray(scores, counter);
cout << "\nAverage Score: "
<< " " << averageArray(scores, counter) << endl
<< endl;
cout << "Press any key to continue...";
delete[] scores;
scores = nullptr;
system("pause>0");
}
void orderArray(double* array, int size)
{
int counterx;
int minIndex;
int minValue;
for (counterx = 0; counterx < (size - 1); counterx++) {
minIndex = counterx;
minValue = *(array + counterx);
for (int index = counterx + 1; index < size; index++) {
if (*(array + index) < minValue) {
minValue = *(array + index);
minIndex = index;
}
}
*(array + minIndex) = *(array + counterx);
*(array + counterx) = minValue;
}
}
double averageArray(double* array, int size)
{
int x;
double total{};
for (x = 0; x < size; x++) {
total += *(array + x);
}
double average = total / size;
return average;
}
void showArray(double* array, int size)
{
for (int i = 0; i < size; i++) {
cout << " " << *(array + i) << endl;
}
}
I try to start my answers with a brief code review:
#include <iostream>
#include <iomanip>
using namespace std; // Bad practice; avoid
void showArray(double* array, int size);
double averageArray(double* array, int size);
void orderArray(double* array, int size);
int main()
{
double* scores = nullptr;
int counter;
double numberOfScores;
cout << "\nHow many test scores will you enter? ";
cin >> numberOfScores;
// This is not input validation, I can enter two consecutive bad values,
// and the second one will be accepted.
if (numberOfScores < 0) {
// Weird formatting, this blank line
cout << "The number cannot be negative.\n"
<< "Enter another number: ";
cin >> numberOfScores;
}
// The homework, as presented, doesn't say you have to treat 0 differently.
if (numberOfScores == 0) {
cout << "You must enter a number greater than zero.\n"
<< "Enter another number: ";
cin >> numberOfScores;
}
scores = new double[numberOfScores];
// Declare your loop counter in the loop
for (counter = 0; counter < numberOfScores; counter++) {
cout << "Enter test score " << (counter + 1) << ": ";
cin >> *(scores + counter);
if (*(scores + counter) < 0) {
cout << "Negative scores are not allowed. " << endl
<< "Enter another score for this test : ";
cin >> *(scores + counter);
}
}
orderArray(scores, counter); // Why not use numberOfScores?
cout << "\nThe test scores in ascending order, and their average, are: " << endl
<< endl;
cout << " Score" << endl;
cout << " -----" << endl
<< endl;
showArray(scores, counter); // Same as above.
cout << "\nAverage Score: "
<< " " << averageArray(scores, counter) << endl
<< endl;
cout << "Press any key to continue...";
delete[] scores;
scores = nullptr;
system("pause>0"); // Meh, I suppose if you're on VS
}
void orderArray(double* array, int size)
{
int counterx;
int minIndex;
int minValue; // Unnecessary, and also the culprit
// This looks like selection sort
for (counterx = 0; counterx < (size - 1); counterx++) {
minIndex = counterx;
minValue = *(array + counterx);
for (int index = counterx + 1; index < size; index++) {
if (*(array + index) < minValue) {
minValue = *(array + index);
minIndex = index;
}
}
*(array + minIndex) = *(array + counterx);
*(array + counterx) = minValue;
}
}
double averageArray(double* array, int size)
{
int x;
double total{};
for (x = 0; x < size; x++) {
total += *(array + x);
}
double average = total / size;
return average;
}
void showArray(double* array, int size)
{
for (int i = 0; i < size; i++) {
cout << " " << *(array + i) << endl;
}
}
When you are sorting your array, you keep track of the minValue as an int and not a double. That's why your average of the sample input is incorrect. 45.1 is truncated to 45 for your calculations. You don't need to keep track of the minValue at all. Knowing where the minimum is, and where it needs to go is sufficient.
But as I pointed out, there are some other serious problems with your code, namely, your [lack of] input validation. Currently, if I enter two consecutive bad numbers, the second one will be accepted no matter what. You need a loop that will not exit until a good value is entered. It appears that you are allowed to assume that it's always a number at least, and not frisbee or any other non-numeric value.
Below is an example of what your program could look like if your professor decides to teach you C++. It requires that you compile to the C++17 standard. I don't know what compiler you're using, but it appears to be Visual Studio Community. I'm not very familiar with that IDE, but I imagine it's easy enough to set in the project settings.
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
// Assumes a number is always entered
double positive_value_prompt(const std::string& prompt) {
double num;
std::cout << prompt;
do {
std::cin >> num;
if (num <= 0) {
std::cerr << "Value must be positive.\n";
}
} while (num <= 0);
return num;
}
int main() {
// Declare variables when you need them.
double numberOfScores =
positive_value_prompt("How many test scores will you enter? ");
std::vector<double> scores;
for (int counter = 0; counter < numberOfScores; counter++) {
scores.push_back(positive_value_prompt("Enter test score: "));
}
std::sort(scores.begin(), scores.end());
for (const auto& i : scores) {
std::cout << i << ' ';
}
std::cout << '\n';
std::cout << "\nAverage Score: "
<< std::reduce(
scores.begin(), scores.end(), 0.0,
[size = scores.size()](auto mean, const auto& val) mutable {
return mean += val / size;
})
<< '\n';
}
And here's an example of selection sort where you don't have to worry about the minimum value. It requires that you compile to C++20. You can see the code running here.
#include <iostream>
#include <random>
#include <vector>
void selection_sort(std::vector<int>& vec) {
for (int i = 0; i < std::ssize(vec); ++i) {
int minIdx = i;
for (int j = i + 1; j < std::ssize(vec); ++j) {
if (vec[j] < vec[minIdx]) {
minIdx = j;
}
}
int tmp = vec[i];
vec[i] = vec[minIdx];
vec[minIdx] = tmp;
}
}
void print(const std::vector<int>& v) {
for (const auto& i : v) {
std::cout << i << ' ';
}
std::cout << '\n';
}
int main() {
std::mt19937 prng(std::random_device{}());
std::uniform_int_distribution<int> dist(1, 1000);
std::vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(dist(prng));
}
print(v);
selection_sort(v);
print(v);
}
I opted not to give your code the 'light touch' treatment because than I would have done your homework for you, and that's just not something I do. However, the logic shown should still be able to guide you toward a working solution.

C++: How to see if an element in an array is over a certain value?

New to C++, so I apologize in advance for my ineptitude.
I need to write a function outside of function Main that checks the elements of an array (that were entered by the user) to see if they are over 10. If they are, I need to print that number of elements as well as a list of the elements themselves. If they aren't, I need to display a message that says there aren't any.
I've tried various things, but this is the one that I keep coming back to. Can you help out?
void print_over_ten(const int list[], int length)
//list[] contains user entered elements
//length contains the length of the array, list[]
{
int index=0; //counter
int amount; //number of elements over 10
int number_over_ten; //variable for numbers over ten
cout << "\nThese numbers are over ten: ";
if (index > 10 && index <= length)
{
number_over_ten = index-1;
cout << number_over_ten << " ";
index++;
}
else
cout << "\nThere are no numbers over 10.\n";
amount = index;
cout << "There are " << amount << " numbers over 10.\n";
}
I think most of that is probably wrong, so feel free to trash that.
Any help is greatly appreciated. Thanks!
If you just need to count the matching elements, you can use a simple loop, eg:
void print_over_ten(const int list[], int length)
{
int amount = 0;
for (int i = 0; i < length; ++i)
{
if (list[i] > 10)
++amount;
}
if (amount > 0)
cout << "There are " << amount << " numbers over 10.";
else
cout << "There are no numbers over 10.";
}
Or, the standard std::count_if() algorithm, eg:
#include <algorithm>
void print_over_ten(const int list[], int length)
{
size_t amount = std::count_if(list, list+length, [](int i){ return i > 10; });
if (amount > 0)
cout << "There are " << amount << " numbers over 10.";
else
cout << "There are no numbers over 10.";
}
But, if you need to actually display the individual numbers that match, you will need to compare each number individually, eg:
void print_over_ten(const int list[], int length)
{
for(int i = 0; i < length; ++i)
{
if (list[i] > 10)
{
int amount = 1;
cout << "These numbers are over ten: " << list[i];
for (++i; i < length; ++i)
{
if (list[i] > 10)
{
++amount;
cout << " " << list[i];
}
}
cout << "\nThere are " << amount << " numbers over 10.";
return;
}
}
cout << "There are no numbers over 10.";
}
Or, you could gather the matching numbers into a container, like a std::vector, eg:
#include <vector>
void print_over_ten(const int list[], int length)
{
std::vector<int> numbers;
for (int i = 0; i < length; ++i)
{
if (list[i] > 10)
numbers.push_back(list[i]);
}
if (!numbers.empty())
{
cout << "These numbers are over ten:";
for(int i : numbers) {
cout << " " << i;
}
cout << "\nThere are " << numbers.size() << " numbers over 10.";
}
else
cout << "There are no numbers over 10.";
}
Your if condition is mostly right, but you need to do that check as you iterate over the array with a loop:
for (int i = 0; i < length; ++i)
{
if (list[i] > 10)
++index;
}
if (index > 10)
cout << "There are " << index << " numbers over 10.\n";
else
cout << "\nThere are no numbers over 10.\n";
Minor note on naming: the variable index doesn't describe what it does. You should probably call it counter as you have written in a comment, or amount, as you you have later assigned it to a variable with that name.
Even better than a loop is to use an algorithm like this:
int amount = std::count_if(list, list + length, [](int i) { return i > 10; });
You can simplify this a lot by using std::copy_if from the <algorithm> STL file:
std::vector<int> get_over_10(const int list[], int length) {
std::vector<int> over_10;
std::copy_if(list, list+length, std::back_inserter(over_10),
[](int i) { return i > 10; });
return over_10;
}

Iterating through array using loop in c++ and program says "exit status -1"?

So I am trying to get comfortable with arrays for my HW assignments. I have two loops. First loop iterates through the sequence, that's good and well I think I dont know. Then the second loop is supposed to display all inputs the user inputted depending on how big size_of_array is (in this case, it's 5, so that should be 5 cars the user enters).
When i run it, the first part works just fine in terms of taking input, but the second part F R E A K S out and gives me "exit status -1" wtf?!?!?!??!
Appreciate the help:
#include <iostream>
using namespace std;
int main()
{
int size_of_array = 5;
string ideal_cars[size_of_array];
int count;
for (count = 1; count <= size_of_array; count++)
{
cout << "Enter car number " << count << "." << "\n";
cin >> ideal_cars[count];
}
for (count = 0; count <= size_of_array; count++)
{
cout << "You entered " << ideal_cars[count] << ".";
}
}
The first index of an array is 0, so when size_of_array is 5, the possible indices are 0, 1, 2, 3, 4.
The 1st element is ideal_cars[0].
The 2nd element is ideal_cars[1].
The 3rd element is ideal_cars[2].
The 4th element is ideal_cars[3].
The 5th element is ideal_cars[4].
ideal_cars[5] is out of range and not allowed. For a graphical illustration, see http://www.cplusplus.com/doc/tutorial/arrays.
So in your for loop you need to make sure count is less and not equal to size_of_array:
for (count = 0; count < size_of_array; count++)
Example:
#include <iostream>
using namespace std;
int main()
{
int size_of_array = 5;
string ideal_cars[size_of_array];
int count;
for (count = 0; count < size_of_array; count++)
{
cout << "Enter car number " << count << "." << endl;
cin >> ideal_cars[count];
}
for (count = 0; count < size_of_array; count++)
{
cout << "You entered " << ideal_cars[count] << "." << endl;
}
return 0;
}
Demo: https://ideone.com/LWbSeu.

How to print index number of an array element?

So Im doing exercise where I have to ask the user to input the number of pancakes eaten by 10 people, print out who ate the most pancakes and then organize the list from greatest to smallest, basically I have to print out:
Person 3: Ate 10 pancakes , Person 5: Ate 9 pancakes ,Person 8: Ate 8 pancakes
However after using bubble sort I cant match the person with the right value, because bubble sort swaps them! Does anyone know of any way to fix this? For example is there another way to organize the values in an array without using bubble sort?
void getPancakes()
{
int x = 0;
int temp;
for(int y = 0; y < 10; y++)
{
++x;
cout << "How many pancakes did person " << x << " eat?" << endl;
cin >> pancakes[y];
}
}
void displayArray(int theArray[],int sizeOfArray)
{
int temp;
int i,j;
int q = 10;
for(i = 0; i <= sizeOfArray - 1 ; i++)
{
for(j = i+1 ; j < sizeOfArray ; j++)
{
if(theArray[i] < theArray[j])
{
temp = theArray[i];
theArray[i] = theArray[j];
theArray[j] = temp;
}
}
}
cout << endl;
for(i = 0; i < 10; i++)
cout << "Person " << i+1 << " ate " << theArray[i] << " pancakes" << endl;
}
Like Cody said, you'll have to store both values. As #HgMs indicated you could you a class, or a struct, which is a class with only public data members. Here's an example:
struct person{
int id;
int pancakes;
};
int main(){
const int totalPeople = 10;
person personArray[totalPeople];
for (int i = 0; i < totalPeople; ++i){
cout << "How many pancakes did person " << i << " eat? ";
personArray[i].id = i;
cin >> personArray[i].pancakes;
}
for (int i = 0; i < totalPeople; ++i){
cout << "id: " << personArray[i].id << "\t" << "Pancakes eaten: " << personArray[i].pancakes << endl;
}
return 0;
}
You can then iterate over the array and look at the number of pancakes each person has eaten using the '.' to access the property.
EDIT: A bubble sort would work fine.

Entering 20 numbers into an array with no duplicates

int main()
{
int theArray [20] = {0};
int userInput = 0;
int populateCount = 0;
cout << "Enter 20 integers between 10 and 100 inclusive. " << endl;
while (populateCount < 20)
{
cin >> userInput;
theArray[populateCount] = {userInput};
if (userInput<10||userInput>100)
{
cout << "That is not a legal input. " << endl;
populateCount - 2;
}
else
{
populateCount++;
}
}
cout << "\n";
for (int i = 0; i < 20; i++)
{
cout << theArray[i] << endl;
}
}
I've got the baseline of my code done. The user enters twenty numbers and they're added to the array. If it's less than 10 or greater than 100 it's not a legal input, I subtract from the count, and they're allowed to go again. Then after the user finishes plugging in numbers it prints the array. However, I've been trying different if statements inside the array to eliminate duplicates, such as (if theArray[i] == theArray[i+1] then [i+1] = 0) I suppose that could work if I incorporated a sort to get all the 0's at the end, but is there a more efficient way to do this?
Before I go to the answer I suggest we clean it up slightly to make the problem more clear and remove other confusion.
Misconception
The statement populateCount - 2 has no effect.. instead you are simply not incrementing populateCount which is why the loop doesn't advance.
I would suggest something of this format within the loop. It puts the 'happy' path first, which will also make for some clearer ways to handle the second part.
if (userInput >= 10 && userInput <= 100 ) {
theArray[populateCount++] = userInput;
}
else {
std::cout << userInput << " is not legal input, must enter value "
<< "between 10 and 100. " << std::endl;
}
Preface
Before we attack the problem first let's refactor so that we can break it down to a single function so that as we work we don't disturb everything else as well as gain flexibility for testing and simplify readability.
Refactor
/* this code is responsible for doing what is needed to
* only insert unique items */
bool insert( const int& input, int* array, int num_elements ) {
// the fun part!
// more to follow shortly
};
/* gets user input forcing input to be between min and max */
int getUserInput(int min, int max) {
bool found = false;
int result = 0;
/* this can be done with less code but this makes it easy
* to see whats going on */
while ( !found ) {
cout << "Please enter a value between " << min << " and " << max << "." << endl;
cin >> result;
if ( result >= min && result <= max ) {
found = true; //yes we could break or return from here
} else {
cout << result << " invalid. "<< endl;
}
}
return result;
};
void printArray( const int* array, const int& size ) {
for (int i = 0; i < size; i++)
{
cout << array[i] << endl;
}
};
int main()
{
const int totalElements = 20;
int theArray [totalElements] = {0};
int userInput = 0;
int populateCount = 0;
int minVal = 10;
int maxVal = 100;
cout << "Enter " << totalElements << " integers between "
<< minVal << " and " << maxVal << " inclusive. " << endl;
while ( populateCount < numElements )
{
//this will percievably loop until it's good
userInput = getUserInput(minVal, maxVal);
if ( insert( userInput, theArray, populateCount ) )
++populateCount; //increments if we did insert it
}
}
cout << endl;
printArray( theArray, totalElements );
}
Attacking the problem
Ok so now our problem is simple, we just have to write the insert function. There are a couple of choices here, you can check each element in turn which as you said can be slow, O(n), or we could sort the array to make it quick, O(log n) + cost of sorting. Other possibilities I presume aren't available are using a std::set instead of an array, or using STL to do the work of sorting and finding. Note that in these modes insert won't actually do an insertion if the number is already present.
Another unique idea is to use an array of bools size max-min, and simply flag the index of input-min as true when you find it. This will be fast at the cost of size depending upon the gap between min and max. (this is essentially a hash function)
The advantage we are at from a refactor is that you can in turn write and try each of these solutions and even feed them the same canned input now that we've refactored so that you can try and time each one. For timing I would heavily suggest you add lots of numbers and consider greatly expanding the min and max to understand the scalability of each choice