Sunday, August 2, 2009

Program Help C++?

Hi all I have a program with 2 vectors in it.





vector%26lt;string%26gt; names(5);


vector%26lt;int%26gt; scores(5);





In this program it is storing the names of the students and there test scores like so.





Name: Mike


Score: 98





The name "Mike" is stored in the string vector and the "98" is stored in the int vector.





Ok so great that all works.





I am using the accumulate function from the numeric header file to add all the scores together and then I am dividing it by the number of elements in the vector, this case 5, to get the average grade.





That all works fine but I want to be able to find out which person has the lowest score and which has the highest and I want it to display the name of the person with the highest and with the lowest not the score they have.





So it should ouput something like this( showing multiple names for those with the same score):





Lowest score: Joe, Bob





Highest Score: Mike, Sam





Does anyone know how I can accomplish this?





Thanks for your time!

Program Help C++?
It takes a bit of work to understand the standard library, but there are functions there that do all of what you want (unless the course instructor wants you to write it yourself. In that case, do not listen to me).





First, as the other posters have mentioned, it's best to combine the score and name together so you can sort by score without losing track of which name goes with which score.





*edited to add*


From reading your follow up comments, it looks like you may not understand structs and arrays of structs.





You understand vectors of ints:


vector%26lt;int%26gt; vi; // holds many ints





Watch this:


struct TestResult {


string name;


int score;


};





TestResult tr; // This is one TestResult, it has a single name and score


vector%26lt;TestResult%26gt; vtr; // This hold many TestResults, each with it's own name and score





tr.name = "Joe";


tr.score = 80;


vtr.push_back(tr); // Add JOe, 80 to the result vector


tr.name = "Larry";


tr.score = 75;


vtr.push_back(tr); // Add Larry, 75 to the result vector





cout %26lt;%26lt; vtr[0].name %26lt;%26lt; ", " %26lt;%26lt; vtr[0].score %26lt;%26lt; endl;


// outputs "Joe, 80" to the console





when we sort the vector, each name and score stay connected to each other. Putting them in separate arrays makes for an enormous amount of work keeping them together.





** end addition **





One of the good things about the standard library is that all of the routines that use a comparison function allow you to pass in your own function. This way you can sort a complex data structure the way you want. You can also overload operator %26lt; for your class if having only one sorting method is OK.





#include %26lt;algorithm%26gt; // copy, sort, some other stuff


using namespace std;





struct TestResult {


string name;


int score;


};





vector%26lt;TestResult%26gt; results;


// populate results vector





bool SortByScore(TestResult const %26amp;r1, TestResult const %26amp;r2)


{


return r1.score %26lt; r2.score;


}





// Sort the vector by increasing score


sort(results.begin(), results,end(), SortByScore);





Now to find the possibly multiple lows and highs.


vec.begin() points to lowest, vec.end()-1 points to highest.


To find multiples, use equal_range()





iterator_pair = equal_range(results.begin(), results,end(), *(results.begin()), SortByScore);





The above gives you a pair of iterators that describe the range that is equal to the first element of results (which must be the lowest after sorting. Finding the highest should be clear. Also, understanding iterator_pair is up to you.





Getting your head around iterators can be tough at first, but it is a very important concept when using the standard library.
Reply:ok.. 1stly, I am not a C++ programmer, so you may need to find some translations to what I am telling you, but I think, you need to do this





sort the scores vector. Every time you swap the positions of two entries in that vector, ensure that the corresponding positions in the names vector get swapped as well. Once the sorting is over, you should have a situation where both vectors are sorted on scores and then running through the score vector will give you the lowest and highest score and you can get their names as well.





That approach is advisable only if you are really hung up on using vectors this way. Why dont you create a struct/class with 2 member variables: score and name


Then create a single vector of objects of this above class.


That ways, the names and the scores will always stay together, and then simply sorting this vector for member.score will give you what you want.





my 2 cents
Reply:When you sort from low to high scores, you should keep an array of ranks (ra) so that ra[0] has the index of the elemnt in in scores[] with the lowest grade, and so forth. Suppose scores[3] is the lowest. Then ra[0] = 3, and 3 is also the index of the name in names [].





If the lowest score is a tie, you get ra[0], ra[1] and so on until the next score is different. For the highest, you start at ra[4] and step down to ra[3] etc. until the score changes.





With the rank vector, the program is one sort function and two loops to find min and max. The index is an array itself.





Good luck.
Reply:I would use STL algorithms.





1. find the max.


vector%26lt;int%26gt;::iterator maxg =


max_element(score.begin(), score.end());





2. using advance and distance, find the iterator for the person with the highest score.





vector%26lt;string%26gt;::iterator maxn = names.begin();


advance(maxn, distance(score.begin(), maxg));


cout %26lt;%26lt; "Highest Score: " %26lt;%26lt; *maxn %26lt;%26lt; endl;
Reply:Looks like what you really want to do is:





struct scores


{


string m_Name;


int m_Score;


};





then...





vector%26lt;scores%26gt; Scores;





then...





score%26amp; GetHighestScore()


{


int high_score_index = 0;


int high_score = 0;


for ( int i = 0; i %26lt; Scores.size(); i++ )


{


if ( Scores[i].m_Score %26gt; high_score )


{


high_score = Scores[i].m_Score;


high_score_index = i;


}


return Scores[i];


}


}





This is untested, I just wrote it here, but looks like what you need.

song words

No comments:

Post a Comment