Based on what you stated: this is how I would design the program. I could have even made it simpler looking by using a struct
or class
, but I'm gathering you are not that far in your course of training. Even this might be a bit more advanced than what is being asked. You did mention parallel arrays
. Instead of arrays
I'm using std::vectors
in place of it. You can easily swap out the vectors
with regular arrays
, however the functions for doing the calculations would change since I'm using library
functions that work on containers. With raw arrays
you would have to do a bunch of for
& while
loops
and comparison
checks while also doing bounds
checks
of those arrays
. Your overall program would look similar to this.
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <fstream>
// Typedefs
typedef std::vector<std::string> Strings;
typedef std::vector<unsigned> Values;
unsigned countToys( const Values& toys );
void determineRatings( const Values& toys, Values& ratings );
unsigned count5StarElves( const Values& toys );
std::string getBestElf( const Strings& elves, const Values& toys );
std::string getWorstElf( const Strings& elves, const Values& toys );
void displayStats( const unsigned numElves, const unsigned fiveStarElves,
const Strings& elves, const Values& toys, const Values& ratings,
const std::string& bestElf, const std::string& worstElf );
int main() {
// Create Containers Giving 50 available spots.
Strings elves;
elves.resize( 50 );
Values ratings;
ratings.resize( 50 );
Values toysMade;
toysMade.resize( 50 );
// Create, Open, Read From File & Close It
unsigned numElves = 0;
std::ifstream file;
file.open( "elves.dat" );
while ( file >> elves[numElves] >> toysMade[numElves] ) {
numElves++; // Need this to resize containers.
}
file.close();
// Adjust containers to fit number of elves.
const std::size_t newSize = numElves;
elves.resize( newSize );
ratings.resize( newSize );
toysMade.resize( newSize );
// Get The Stats -- Counting the total number of elves is called within the display function.
determineRatings( toysMade, ratings );
unsigned fiveStarElves = count5StarElves( ratings );
std::string bestElf = getBestElf( elves, toysMade );
std::string worstElf = getWorstElf( elves, toysMade );
// Display The Results
displayStats( numElves, fiveStarElves, elves, toysMade, ratings, bestElf, worstElf );
std::cout << "\nPress any key and enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
unsigned countToys( const Values& toys ) {
unsigned total = std::accumulate( toys.begin(), toys.end(), 0 );
return total;
}
void determineRatings( const Values& toys, Values& ratings ) {
for ( unsigned i = 0; i < toys.size(); i++ ) {
if ( toys[i] >= 500 ) {
ratings[i] = 5;
}
if ( toys[i] < 500 && toys[i] >= 300 ) {
ratings[i] = 3;
}
if ( toys[i] < 300 && toys[i] >= 200 ) {
ratings[i] = 1;
}
if ( toys[i] < 200 ) {
ratings[i] = 0;
}
}
};
unsigned count5StarElves( const Values& ratings ) {
unsigned fiveStartCount = 0;
for ( auto val : ratings ) {
if ( val == 5 ) {
fiveStartCount++;
}
}
return fiveStartCount;
}
std::string getBestElf( const Strings& elves, const Values& toys ) {
auto it = std::max_element( toys.begin(), toys.end() );
if ( it == toys.end() ) {
return "";
}
// for random access containers with O(1) - constant
return elves[it - toys.begin()];
// If using non-random containers use the following with O(n) - linear
// return std::distance(toys.begin(), it );
}
std::string getWorstElf( const Strings& elves, const Values& toys ) {
auto it = std::min_element( toys.begin(), toys.end() );
if ( it == toys.end() ) {
return "";
}
// for random access containers with O(1) - constant
return elves[it - toys.begin()];
// If using non-random containers use the following with O(n) - linear
// return std::distance(toys.begin(), it);
}
void displayStats( const unsigned numElves, const unsigned fiveStarElves,
const Strings& elves, const Values& toys, const Values& ratings,
const std::string& bestElf, const std::string& worstElf ) {
std::cout << "***********************************************\n";
std::cout << "* Welcome To Santa's Workshop: *\n";
std::cout << "* We have " << numElves << " working elves. *\n";
std::cout << "* Our Elves made a total of " << countToys( toys ) << " toys today. *\n";
std::cout << "***********************************************\n\n";
std::cout << "Here are their stats:\n";
std::cout << "===============================================\n";
// Calculate the longest name for proper screen output formatting.
std::size_t maxLength = 0;
for ( const auto name : elves ) {
if ( name.length() > maxLength ) {
maxLength = name.length();
}
}
std::cout << std::left << std::setw( maxLength + '\t' ) << "Elf Name:" << std::setfill( ' ' ) << "Toys Made:\t\tRating:\n" << std::endl;
for ( unsigned i = 0; i < numElves; i++ ) {
std::cout << std::left << std::setw( maxLength + '\t' ) << elves[i] << std::left << std::setfill( ' ' )
<< std::setw( 4 ) << std::left << toys[i] << std::left
<< "\t\t" << ratings[i] << " stars" << std::endl;
}
std::cout << "\n\n";
// Additional Stats:
std::cout << "There are " << fiveStarElves << " 5 Star Elves!\n";
std::cout << "The Best Elf is: " << bestElf << std::endl;
std::cout << "The Worst Elf is: " << worstElf << std::endl;
}
elves.dat
Smiley 662
Curley 88
Clementine 335
Jasper 105
Lucinda 775
Brunhilda 103
Florence 441
Oskar 820
Snowflake 990
Bernard 690
Punch 298
Chuckie 10
Frosty 102
Snowman 311
April 830
Merry 299
Sunshine 331
Buddy 1234
Carol 271
Misty 111
Harold 52
Henry 292
Twinkle 308
Starlight 703
Burr 112
Angelica 444
Bluenose 689
Harry 254
Twinkle 259
Stardust 121
Greensleeves 453
Noel 312
Happy 209
Yukon 534
Snowcap 190
Northpole 598
Edit - If you want to do something a little fancy in the display function. Change the displayStats()
function to this:
void displayStats( const unsigned numElves, const unsigned fiveStarElves,
const Strings& elves, const Values& toys, const Values& ratings,
const std::string& bestElf, const std::string& worstElf ) {
std::cout << "***********************************************\n";
std::cout << "* Welcome To Santa's Workshop: *\n";
std::cout << "* We have " << numElves << " working elves. *\n";
std::cout << "* Our Elves made a total of " << countToys( toys ) << " toys today. *\n";
std::cout << "***********************************************\n\n";
std::cout << "Here are their stats:\n";
std::cout << "===============================================\n";
// Calculate the longest name for proper screen output formatting.
std::size_t maxLength = 0;
for ( const auto name : elves ) {
if ( name.length() > maxLength ) {
maxLength = name.length();
}
}
std::cout << std::left << std::setw( maxLength + '\t' ) << "Elf Name:" << std::setfill( ' ' ) << "Toys Made:\t\tRating:\n" << std::endl;
// A little bit of magic: (not really) just pretty
Strings stars;
std::string str;
for each (auto star in ratings) {
if ( star == 0 ) {
str = std::string( "" );
}
if ( star == 1 ) {
str = std::string( "*" );
}
if ( star == 3 ) {
str = std::string( "***" );
}
if ( star == 5 ) {
str = std::string( "*****" );
}
stars.push_back( str );
}
for ( unsigned i = 0; i < numElves; i++ ) {
std::cout << std::left << std::setw( maxLength + '\t' ) << elves[i] << std::left << std::setfill( ' ' )
<< std::setw( 4 ) << std::left << toys[i] << std::left
<< "\t\t" << stars[i] /*ratings[i] << " stars"*/ << std::endl;
}
std::cout << "\n\n";
// Additional Stats:
std::cout << "There are " << fiveStarElves << " 5 Star Elves!\n";
std::cout << "The Best Elf is: " << bestElf << std::endl;
std::cout << "The Worst Elf is: " << worstElf << std::endl;
}