How can I sort in descending order? - c++

I'm trying to sort for the top and second top value of totalRevenue and its name. I've tried to sort them in descending order this way but I could not figure it out how to make it work. Can anyone please help me out?
First two entries:
1002 Hammer 23.65 203
1024 Nails 6.95 400
Here is the code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// Structure to hold statistics
struct Selling {
int productNumber;
string name;
double price;
int soldNumber;
double totalRevenue[];
};
int main()
{
ifstream statFile;
string productName;
double price;
int productNumber, soldNumber;
Selling *productArray[100];
Selling *aSelling;
int numProduct = 0;
int man = 0;
statFile.open("sales.txt");
while (numProduct < 100 && statFile >> productNumber >> productName >> price >> soldNumber)
{
Selling *aSelling = new Selling;
aSelling->productNumber = productNumber;
aSelling->name = productName;
aSelling->price = price;
aSelling->soldNumber = soldNumber;
aSelling->totalRevenue[] = aSelling->price * aSelling->soldNumber;
productArray[numProduct++] = aSelling;
//cout << aSelling->productNumber<< " " << aSelling->name << " " << aSelling->price << " " << aSelling->soldNumber << " " << aSelling->totalRevenue << endl;
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (aSelling->totalRevenue[i] > aSelling->totalRevenue[j]) {
man = aSelling->totalRevenue[i];
aSelling->totalRevenue[i] = aSelling->totalRevenue[j];
aSelling->totalRevenue[i] = man;
}
}
}
for (int i = 0; i < 2; i++) {
cout << "The top selling product is " << aSelling->name << "with total sales of " << aSelling->totalRevenue[i] << endl;
cout << "The second top selling product is " << aSelling->name << "with total sales of " << aSelling->totalRevenue[i - 1] << endl;
}
}
And there is an unexpected expression error at the line aSelling->totalRevenue[] = aSelling->price * aSelling->soldNumber; which I don't understand.

There is some confusion on the arrays to sort:
you should define totalRevenue as a double, not an array of doubles,
should be sort the first numProduct elements of the array productArray based on the criteria totalRevenue and name, the order is determined by the comparison operator used. Only compare the second criteria if the first criteria give equal values.
Here is a modified version:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// Structure to hold statistics
struct Selling {
int productNumber;
string name;
double price;
int soldNumber;
double totalRevenue;
};
int compareSellings(const Selling *a, const Selling *b) {
// sort in decreasing order of totalRevenue
if (a->totalRevenue > b->totalRevenue) return -1; // a comes before b
if (a->totalRevenue < b->totalRevenue) return +1; // b comes before a
// sort in increasing order of name for the same totalRevenue
if (a->name < b->name) return -1; // a comes before b
if (a->name > b->name) return +1; // b comes before a
return 0;
}
int main() {
ifstream statFile;
string productName;
double price;
int productNumber, soldNumber;
Selling *productArray[100];
int numProduct = 0;
statFile.open("sales.txt");
while (numProduct < 100 && statFile >> productNumber >> productName >> price >> soldNumber) {
Selling *aSelling = new Selling;
aSelling->productNumber = productNumber;
aSelling->name = productName;
aSelling->price = price;
aSelling->soldNumber = soldNumber;
aSelling->totalRevenue = price * soldNumber;
productArray[numProduct++] = aSelling;
//cout << aSelling->productNumber<< " " << aSelling->name << " "
// << aSelling->price << " " << aSelling->soldNumber << " "
// << aSelling->totalRevenue << endl;
}
for (int i = 0; i < numProduct; i++) {
for (int j = 0; j < numProduct; j++) {
if (compareSellings(productArray[i], productArray[j]) > 0) {
Selling *aSelling = productArray[i];
productArray[i] = productArray[j];
productArray[j] = aSelling;
}
}
}
cout << "The top selling product is " << productArray[0]->name
<< ", with total sales of " << productArray[0]->totalRevenue << endl;
cout << "The second selling product is " << productArray[1]->name
<< ", with total sales of " << productArray[1]->totalRevenue << endl;
return 0;
}
Further remarks:
you might use a more efficient sorting method
you should free the allocated objects
you should use <algorithms> and dynamic arrays of objects instead of allocating the objects with new and manipulating naked pointers.
you should handle exceptions

Related

Why isn't my array incrementing properly?

I am in a C++ class and I am having trouble with the project. The idea of the project is to create an ordering application using structs and arrays. As far as I can tell the program is working as intended except for the how many items of each item the person ordered part of my printMenu function. If I am mistaken and or you find more errors please let me know.
Here is the code:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
struct dinnerItemType
{
string dinnerItem;
double dinnerPrice;
int dinnerOrdered;
};
void getFood(dinnerItemType ourMenu[], int &size);
void printMenu(dinnerItemType ourMenu[], int size);
void printCheck(dinnerItemType ourMenu[], int size);
//Defines the global tax constant of 6%
const double TAX = 0.06;
int main()
{
dinnerItemType ourMenu[150];
int size = 0;
getFood(ourMenu, size);
printMenu(ourMenu, size);
printCheck(ourMenu, size);
system("pause");
return 0;
}
void getFood(dinnerItemType ourMenu[], int &size)
{
ourMenu[0].dinnerItem = "Chicken Sandwich";
ourMenu[0].dinnerPrice = 4.45;
ourMenu[0].dinnerOrdered = 0;
ourMenu[1].dinnerItem = "Fries";
ourMenu[1].dinnerPrice = 2.47;
ourMenu[1].dinnerOrdered = 0;
ourMenu[2].dinnerItem = "Truffle Fries";
ourMenu[2].dinnerPrice = 0.97;
ourMenu[2].dinnerOrdered = 0;
ourMenu[3].dinnerItem = "Filet 8oz";
ourMenu[3].dinnerPrice = 11.99;
ourMenu[3].dinnerOrdered = 0;
ourMenu[4].dinnerItem = "Fruit Basket";
ourMenu[4].dinnerPrice = 2.44;
ourMenu[4].dinnerOrdered = 0;
ourMenu[5].dinnerItem = "Tea";
ourMenu[5].dinnerPrice = 0.69;
ourMenu[5].dinnerOrdered = 0;
ourMenu[6].dinnerItem = "Water";
ourMenu[6].dinnerPrice = 0.25;
ourMenu[6].dinnerOrdered = 0;
size = 7;
}
void printMenu(dinnerItemType ourMenu[], int size)
{
int number;
int amount;
cout << "Welcome to the restraunt here are your menu items: \n";
for (int i = 0; i < size; i++)
{
cout << (i + 1) << ")";
cout << ourMenu[i].dinnerItem
<< "$"
<< ourMenu[i].dinnerPrice
<< endl;
}
cout << "To order just type in the number associated with the menu item and hit enter.\n"
<< "Once you have completed your order just type in 0 to go to checkout.\n";
cin >> number;
while (number != 0)
{
if (number >= 1 && number <= 8)
{
ourMenu[number - 1].dinnerOrdered++;
}
else
{
cout << "The number does not coorispond with a menu item please try again.\n";
}
cout << "To order just type in the number associated with the menu item and hit enter.\n"
<< "Once you have completed your order just type in 0 to go to checkout.\n";
cin >> number;
}
}
void printCheck(dinnerItemType ourMenu[], int size)
{
double total = 0;
cout << "Your Bill: ";
for (int i = 0; i < size; i++)
{
if (ourMenu[i].dinnerOrdered > 0)
{
total += ourMenu[i].dinnerPrice;
}
}
cout << "Tax: $ " << fixed << setprecision(2) << (total * TAX);
cout << " Ammount Due: $" << (total + (total * TAX)) << endl;
cout << "Thank you come again!" << endl;
}
This line:
total += ourMenu[i].dinnerPrice;
is only adding the cost of one meal to the total, regardless of how many times that meal is ordered.
To fix it: simply multiple the price by the number of times it is ordered:
total += ourMenu[i].dinnerPrice * ourMenu[i].dinnerOrdered;

Printing a receipt using parallel arrays c++

I have been given this assignment for a lab project, and I have everything working until it gets to the receipt part. The issues I am having are 1) printing the incorrect menu items ordered, and 2) getting -42........ number for the pricing. I've looked through this several times and have spoken with others in the class. This is where we are ALL having issues. My TA said to use array[array1[counter]] for this section, but it doesn't seem to work. Can you help me focus on where things are seriously incorrect?
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const int NUM_MENU_ITEMS = 10; // num items on the menu
const int MAX_ORDER_ITEMS = 5; // max num of items per order
const double DISCOUNT_MIN = 20.00; // min subtotal to get discount
const double DISCOUNT_RATE = 0.25; // disc rate for highest-priced item
// Menu: parallel constant arrays
const string menuItem[NUM_MENU_ITEMS] = {
"Burger", "Hot Dog", "Chicken Fingers", "Fries",
"Tots", "Tea", "Coke", "Diet Coke", "Water", "Cookies" };
const double menuPrice[NUM_MENU_ITEMS] = {
3.50, 2.75, 4.25, 2.50, 3.25,
1.00, 1.25, 1.25, 0.25, 2.50 };
int main()
{
// Order: parallel partial arrays of items ordered
// Each item has an item number, quantity ordered, and total price
// TODO: declare a list of item numbers
// TODO: declare a list of quantities
// TODO: declare a list of item prices (menu price X quantity)
// TODO: declare other variables as needed
double total, subtotal, discount;
// receipt line data
string recName;
int recQty;
int j = 0;
double recPrice;
// print menu
cout << "MENU:\n" << fixed << setprecision(2);
cout << "## Item Price\n";
cout << "-- --------------- -------\n";
// TODO: write a loop to print the menu
int i = 0;
int itemNumber[NUM_MENU_ITEMS] = {
0,1, 2, 3, 4, 5, 6, 7, 8, 9 };
while (i <= 9)
{
cout << setw(2) << itemNumber[i] << " " <<
left << setw(15) << menuItem[i] <<
right << " $ " << setw(5) << menuPrice[i] << endl;
i++;
}
cout << endl;
// get order
int counter = 0;
int itemQuantity[MAX_ORDER_ITEMS];
double itemPrice[MAX_ORDER_ITEMS];
int itemOrder[MAX_ORDER_ITEMS];
string itemName[MAX_ORDER_ITEMS];
do {
cout << "Enter quantity and menu item number (0 0 to end):\n";
cout << "Item 0: ";
cin >> itemQuantity[counter] >> itemOrder[counter];
itemOrder[counter] = itemNumber[counter];
itemPrice[counter] = menuPrice[itemOrder[counter]] *
itemQuantity[counter];
itemName[counter] = menuItem[itemOrder[counter]];
counter++;
} while (counter < MAX_ORDER_ITEMS && itemQuantity[counter] != 0);
// TODO: repeat inputs until quantity is 0 or MAX_ORDER_ITEMS exceeded
//{
// //TODO: add an item to the order parallel arrays
// cout << "Item " << menuItem[i] << ": ";
// cin >> itemQuantity[i] >> itemPrice[i];
//}
double maxItemPrice = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
if (itemPrice[counter] > maxItemPrice)
maxItemPrice = i;
}
// find the subtotal price
// TODO: use a loop to calculate the sum of all order prices
subtotal = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
subtotal = subtotal + itemPrice[counter];
}
// discount highest order line by 25% when total > $20
if (subtotal >= DISCOUNT_MIN)
{
// TODO: add a loop to find the maximum item price
discount = DISCOUNT_RATE * maxItemPrice;
}
else
discount = 0;
// calculate the total price
total = subtotal - discount;
// print the receipt
cout << "\n----------------------------\n";
cout << "Item Qty Price\n";
cout << "--------------- --- -------\n";
// TODO: use a loop to print the lines of the receipt
i = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
recName = itemName[i];
recQty = itemQuantity[i];
recPrice = itemPrice[menuPrice[i]];
cout << left << setw(15) << recName << " "
<< right << setw(3) << recQty << " $"
<< setw(6) << recPrice << endl;
}
cout << "\nSubtotal: $" << setw(6) << subtotal << endl;
cout << "Discount: $" << setw(6) << discount << endl;
cout << "Total Price: $" << setw(6) << total << endl << endl;
system("pause");
return 0;
}
In this line in the do while loop:
} while (counter < MAX_ORDER_ITEMS && itemQuantity[counter] != 0);
you have already incremented counter so your while loop is checking a part of the
itemQuantity
array that has not been input yet.
Also, here
double maxItemPrice = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
if (itemPrice[counter] > maxItemPrice)
maxItemPrice = i;
}
counter is a variable used previously and has not been updated. What is counter representing, and what is i?
And again here,
subtotal = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
subtotal = subtotal + itemPrice[counter];
}
Counter is still the same as it was left in the do while loop. Here it should be
subtotal = 0;
for (i = 0; i < MAX_ORDER_ITEMS; i++)
{
subtotal = subtotal + itemPrice[i];
}
Check array parameters closely and make sure what's written is doing what you want it to do. Best of luck!

c++ array showing an error

Hello i am trying to create a program in which you enter your deals and after you're finished you should get a list of the deals . I want to get them displayed with an array but i keep getting an error must have a pointer to object.
#include <iostream>
using namespace std;
int main() {
int deal;
int date;
int type;
int quantity;
int quality;
int end;
int find;
for (deal = 0; deal < 5000; deal++) {
for (date = 0; date < 5000; date++) {
cout << " enter the year,month,day and hour of pruchase in this format YYYY/MM/DD/HH/MM" << endl;
cin >> date;
for (type = 0; type < 5000; type++) {
cout << " enter the mushroom type. 1 = манатарка, 2 = печурка, 3 = кладница 4 = пачи крак, 5 = съренла, 6 = друг вид гъба "<<endl;
cin >> type;
for (quantity = 0; quantity < 5000; quantity++) {
cout << " enter the mushroom quantity " << endl;
cin >> quantity;
for (quality = 0; quality < 5000; quality++) {
cout << "enter the mushroom quality from 1 to 3 " << endl;
cin >> quality;
cout << "Press 1 for a new deal , press 2 to exit" << endl;
cin >> end;
if (end = 2)
{
deal[date];
goto stop;
}
}
}
}
}
}
stop:
for (find = 0; find < 5000; find++) {
int find = 0;
cout << date[find] << ", " << type[find] << ", " << quantity[find] << ", " << quality[find];
//error must have a pointer to object
}
}
Your date, find, etc. variables are defined as scalars. You cannot refer to them date[find]. You should have declared them as arrays/vectors.
deal should be declared as array type of int.

Using arrays and strings together

So I'm trying to create an array that contains some user inputted names, and then associate those names with letter grades from tests (ex: A, B, C, D, F). My question is, how would I use an array to accept the user inputted names?
EDIT:
Sorry this is a bit long, I don't know what part to put that would help out. Totally new to C++ and I can't seem to find anything online regarding the matter, lol.
Here is some code. This program currently asks the user for test scores, then displays and drops the lowest test score, and finally, calculates the average of the scores without the lowest one. The end goal is to ask the user for 5 students names, and 4 scores for each student, then dropping the lowest score for each student and calculating the averages of ALL scores inputted regardless of student.
#include <iostream>
#include <string>
using namespace std;
void getScore(int &);
int findLowest(int [], int);
void calcAverage(int [], int);
int main () {
const int NUM_SCORES = 5;
int scores[NUM_SCORES];
cout << "Welcome to test averages." << endl;
cout << "Please enter scores for " << NUM_SCORES << " students." << endl;
cout << endl;
for (int i = 0; i < NUM_SCORES; i++) {
getScore(scores[i]);
}
for (int i = 0; i < NUM_SCORES; i++) {
cout << "Score " << (i + 1) << ": " << scores[i] << endl;
}
cout << endl;
cout << "The lowest of these scores is " << findLowest(scores, NUM_SCORES) << endl;
calcAverage(scores, NUM_SCORES);
return 0;
}
void getScore(int & s) {
s = -1;
cout << "Please enter a test score: ";
cin >> s;
while (s < 0 || s > 100) {
cout << "Score range must be from 0-100" << endl;
cout << "Please re-enter a score: ";
cin >> s;
}
}
int findLowest(int theArray [], int theArraySize) {
int lowest = theArray[0];
for (int i = 1; i < theArraySize; i++) {
if (theArray[i] < lowest) {
lowest = theArray[i];
}
}
return lowest;
}
void calcAverage(int theArray [], int theArraySize) {
int sum = 0;
for (int i = 0; i < theArraySize; i++) {
sum += theArray[i];
}
double average = (sum - findLowest(theArray, theArraySize)) / (theArraySize - 1.0);
cout << "The average is " << average << endl;
}
Try getline from #include <string>
std::string names[5];
for (int i = 0; i < 5; ++i){
getline(std::cin, names[i]);
}

calculate average of array elements and display them

The problem is:
A Class of 40 students has received their grades for 5 exams. Implement a function that calculates the worst average grade and display the the IDs of all students having the worst average grade.‎
I already calculated the average but do not know how to calculate the WORST average ( as in the lowest average of the 40 students) and displaying the ID numbers that have this number.
This is what I have written so far:
#include<iostream>
#include <iomanip>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
int main()
{
float avg;
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
cout << "Enter an ID number: " << endl;
cin >> x[i];
cout << "Enter 5 grades: " << endl;
for (int j = 0; j < 5; j++)
{
cin >> y[j];
while (y[j]>100)
{
cout << "Please enter a valid grade that is less than a 100: " << endl;
cin >> y[j];
}
total += y[j];
}
avg = total / 5;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg << endl;
}
Something like this:
Note: I have added some important statements!
#include<iostream>
#include <iomanip>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
float AVG[MAX_NUM];
int worstIDCount = 0;
int main()
{
float avg, min = 1001;
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
avg = 0;
total = 0;
cout << "Enter an ID number: " << endl;
cin >> x[i];
cout << "Enter 5 grades: " << endl;
for (int j = 0; j < 5; j++)
{
cin >> y[j];
while (y[j]>100)
{
cout << "Please enter a valid grade that is less than a 100: " << endl;
cin >> y[j];
}
total += y[j];
}
avg = total / 5;
AVG[i] = avg;
if(avg < min)
min = avg;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg << endl;
}
for(int i = 0; i < MAX_NUM; i++)
{
if(AVG[i] == min)
cout << "Student with WORST Average: ID" << x[i] << endl;
}
};
So you want to store these averages in a std::vector<float>, std::sort it and get the lowest. Then go back and find the students that have that average.
working example
#include <iostream>
#include <vector>
#include <functional> // mem_fn
#include <algorithm> // sort, upper_bound
#include <iterator> // ostream_iterator
struct Student_average {
int student_id;
float average;
};
bool compare_student_averages(Student_average const &lhs,
Student_average const &rhs) {
return lhs.average < rhs.average;
}
int main() {
std::vector<Student_average> averages;
// collect the data and populate the averages vector
// ...
sort(begin(averages), end(averages), compare_student_averages);
std::cout << "The worst average is: " << averages.front().average << '\n';
auto end_of_worst_student_averages =
upper_bound(begin(averages), end(averages), averages.front(),
compare_student_averages);
std::cout << "The IDs of the students with the worst averages are:\n";
transform(begin(averages), end_of_worst_student_averages,
std::ostream_iterator<int>(std::cout, "\n"),
std::mem_fn(&Student_average::student_id));
}
Here is a more C++ way of doing this using std::accumulate and std::min_element (I removed the check for anything > 100, for brevity):
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;
const int MAX_NUM = 6;
int x[MAX_NUM];
int y[5];
int main()
{
float avg[5];
float total = 0;
for (int i = 0; i < MAX_NUM; i++)
{
cin >> x[i]; // ID
for (int j = 0; j < 5; ++j)
cin >> y[j]; // grades
// compute the average for this student
avg[i] = std::accumulate(y, y + 5, 0) / 5.0F;
cout << "ID: " << x[i] << endl;
cout << "Average: "<< avg[i] << endl;
}
// compute the worst average
float* worst_average = std::min_element(avg, avg + MAX_NUM);
// get the position in the array where the worst is found
int position = std::distance(avg, worst_average);
// output results
cout << "This person has the worst average: " << x[position]
<<". The average is " << *worst_average << "\n";
}
Note that the averages are stored in an array. The way the average is computed for each person is to use std::accumulate to add up the y array values, and then divide by 5.0.
Since we now have the averages in an aray, we want to find the smallest item in the array. To do that, min_element is used to get us the position of where the element is stored.
The trick here is that min_element returns a pointer to the smallest item, so we need calculate how far this pointer is located from the beginning of the avg array. To do this, the std::distance function is used. This now gives us the position of the smallest item.
The rest of the code just outputs the results.
As you can see, the only loops involved were the input loops. The calculation of the average and the worst average were done using accumulate and min_element, respectively.