Parallel Arrays for toys made by elves c++

276 Views Asked by At

I would really like help with this program, as I can't figure out what to do. I've tried searching online for answers or something that would point me in the right direction, but this is sort of difficult for me since I'm just learning how to code. I would greatly appreciate it!

You are to write a program that will help Santa process the work done by his elves. You will be using a data file called elves.dat. There will be one line for each elf. That line will contain the name of the elf and the number of toys the elf made. You are to read from the file and place the values in parallel arrays. You do not know how many elves there are so you must read until the end of file and count. You will need a third parallel array of strings to record a rating for each elf. You should declare arrays with the capacity for 50 components.

The program should read into the arrays. It should look at the number of toys made by each elf and record a rating in a parallel array. The table below determines the ratings. The program should then print out the arrays side by side in neat, labeled columns. It should print out the total number of toys made by the elves, the number of elves who made more than 500 toys, the name of the elf who made the most toys, and the name of the elf who made the least toys. Each calculation should have a function of its own. NO output should be done in functions that do calculations. All output should be done in one output function. Remember to always pass the number of elements in the array with the array to functions.

Toys Made........Rating

500 or more: ***** 5 stars

between 300 and 499: *** 3 stars

between 200 and 299: * 1 star

under 200: - none

Here's the information in 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

And here's my code, I feel like a have a very basic understanding, but I know I'm not even close! I would appreciate any help, I really need it.

#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

int main() {

  ifstream inFile;
  inFile.open("elves.dat");

  string elfName[50];
  int ToysMade[50];
  int count = 0;
  int i;
  //Read file until you've reached the end                                        
  while (!inFile.eof()){
    inFile >> elfName;
    inFile >> ToysMade;
    count++;}
    cout << "Elf: " << elfName <<endl;
    cout << "Toys made: " << ToysMade <<endl;

    inFile.close();
  return 0;
}
1

There are 1 best solutions below

0
On

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;
}