Is there a way to link input from two different arrays? - c++

I'm having an issue with some school work where I need to create two arrays one for names and one for scores which allows the user to input into both arrays (i.e. Enter the players name:; Enter the players score:). Then I need to print the arrays in descending score and then ascending alphabetical. As a hint we were told: Using the string sort function combine the two arrays into one then sort.
However I can't figure out how to link the two values to one another so that if I enter Nathan with a score of 87 the two values can't be split apart.
This is what I have so far (with some things I was trying to get to work but couldn't):
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string names[10];
int scores[10];
string combine[20];
int count = 0;
while (count < 10){
cout << "Please enter a player's name: ";
cin >> names[count];
cout << "Now enter that player's score: ";
cin >> scores[count];
count++;
}
/*sort(begin(names), end(names));
sort(begin(scores), end(scores));*/
for (int i = 0; i < 10; i++){
cout << names[i] << ": " << scores[i] << "\n";
}
system("pause");
}

You want to "link" them from the very beginning:
struct Student {
string name;
int score;
bool operator<(const Student& rhs) const {
return score > rhs.score || (score == rhs.score && name < rhs.name);
}
};
That way, the sort is easy:
sort(begin(students), end(students));
Otherwise, you'd have to make an array of indices:
int indices[10];
std::iota(begin(indices), end(indices), 0);
And sort that:
std::sort(begin(indices), end(indices), [&](int a, int b){
return scores[a] > scores[b] ||
scores[a] == scores[b] && names[a] < names[b];
});
And then print according to indices:
for (int idx : indices) {
std::cout << names[idx] << " with score " << scores[idx] << '\n';
}

As far as combining the two arrays into one you can do something like this:
// create a struct that of type "result"
// that combines both name and score
struct result
{
string name;
int score;
};
int main()
{
string names[10];
int scores[10];
// array of your struct - same number of elements (10 not 20)
result combine[10];
int count = 0;
while (count < 10){
cout << "Please enter a player's name: ";
cin >> names[count];
cout << "Now enter that player's score: ";
cin >> scores[count];
count++;
}
/*sort(begin(names), end(names));
sort(begin(scores), end(scores));*/
for (int i = 0; i < 10; i++){
cout << names[i] << ": " << scores[i] << "\n";
}
// combine into one array
for(int i = 0; i < 10; ++i)
{
combine[i].name = names[i];
combine[i].score = scores[i];
}
// Now sort the combined array
system("pause");
}

Related

C++ Calculate the biggest, smallest and average number in different functions and print it. Program will fail to do the arithetics properly

The program will sometimes work properly if i only put the numbers in ascending order. It will fail tho if i try to randomly put numbers. The average number will fail to print properly like the arithmetics didnt work at all I would appreciate any help.
Full question here : Define a class named Student with three private data for
registration number, name and grades in 8 courses (table). Also write the following member functions: A function for assigning values to private class data
• A function for displaying the data
• A function for the return of the maximum score
• A function for the return of the minimum score
• A function for the return of the average score
#include <iostream>
#include <string>
using namespace std;
struct Student
{
private:
string name;
string lname;
string mtr;
int grades[8];
int sum;
int dbv = 0;
int mo;
int min;
int max;
int i, n, p;
public:
void insert()
{
int i;
cout << "\nName : ";
cin >> name;
cout << "\nLast name: ";
cin >> lname;
cout << "\nID : ";
cin >> mtr;
for (i = 1; i < 9; i++)
{
cout << i << ") Give number : ";
cin >> grades[i];
sum += grades[i];
}
}
int average()
{
mo = sum / 8;
}
int minimum()
{
min = grades[0];
for (i = 1; i < 9; i++)
{
if (min > grades[i])
{
min = grades[i];
}
}
}
int maximum()
{
max = grades[0];
for (i = 1; i < 9; i++)
{
if (max < grades[i])
{
max = grades[i];
}
}
}
int print()
{
cout << "\nPRINT : \n Name : " << name << "\n Last Name: " << lname << " \nID : " << mtr << "\nAverage : " << mo << "\nMax : " << max << "\nMin : " << min;
}
};
int main()
{
Student std1;
std1.insert();
std1.average();
std1.minimum();
std1.maximum();
std1.print();
}
In insert, you didn't give a value to grades[0]. So in minimum and maximum, you're comparing grades with a memory garbage.
And, the length of the array is 8, so the index has to be in the range from 0 to 7.
But you're trying to access the 8th element. It means you will get memory garbage again or other variables.

How do I convert from arrays to STL vectors?

In my class we recently got introduced to STL vectors. My professor has given us a program that uses arrays, and we are to convert it to use std::vectors instead. He would like us to use iterators, so we're not allowed to use square brackets, the push_back member function, or the at member function. Here's one of the for loops from the program I have to convert:
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
`
I'm just not quite understanding how to convert them. so far, I was kind of able to get this: for (vector <Highscore> :: iterator num = scores.begin(); num < scores.end(); num++)for the for loop. It doesn't quite make sense to me so I was hoping I can get some more tips or even more information on how to convert them. I don't want an answer, simply just a tip. Thank you! (if its of any help, this is the program I am having to convert and these are the four headers we have to use
void getVectorSize(int& size);
void readData(vector<Highscore>& scores);
void sortData(vector<Highscore>& scores);
vector<Highscore>::iterator findLocationOfLargest(
const vector<Highscore>::iterator startingLocation,
const vector<Highscore>::iterator endingLocation);
void displayData(const vector<Highscore>& scores);
above are the headers that have to be used (having to use these instead of the programs headers)
#include <iostream>
using namespace std;
const int MAX_NAME_SIZE = 24;
struct Highscore{
char name[MAX_NAME_SIZE];
int score;
};
void getArraySize(int& size);
void readData(Highscore highScores[], int size);
void sortData(Highscore highScores[], int size);
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int size);
void displayData(const Highscore highScores[], int size);
int main()
{
Highscore* highScores;
int size;
getArraySize(size);
highScores = new Highscore[size];
readData(highScores, size);
sortData(highScores, size);
displayData(highScores, size);
delete [] highScores;
}
void getArraySize(int& size){
cout << "How many scores will you enter?: ";
cin >> size;
cin.ignore();
}
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
void sortData(Highscore highScores[], int numItems) {
for (int count = 0; count < numItems - 1; count++){
swap(highScores[findIndexOfLargest(highScores, count, numItems)],
highScores[count]);
}
}
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int numItems){
int indexOfLargest = startingIndex;
for (int count = startingIndex + 1; count < numItems; count++){
if (highScores[count].score > highScores[indexOfLargest].score){
indexOfLargest = count;
}
}
return indexOfLargest;
}
void displayData(const Highscore highScores[], int size)
{
cout << "Top Scorers: " << endl;
for(int index = 0; index < size; index++)
{
cout << highScores[index].name << ": " << highScores[index].score << endl;
}
}
You maybe looking for one of two things.
If you want to add something to a vector, the function is push_back
vecScores.push_back(value) ; //in a for loop.
https://www.cplusplus.com/reference/vector/vector/push_back/
If you want to add something to a map, you could just use the form of
mapScore[index]=value ; // in a for loop.
https://www.cplusplus.com/reference/map/map/operator[]/
Probably your professor wants you to write something like this:
void readData(std::vector<Highscore>& highScores)
{
for (auto it = highScores.begin(); it != highScores.end(); ++it) {
cout << "Enter the name for score #" << std::distance(highScores.begin(), it) << ": ";
cin.getline(it->name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << std::distance(highScores.begin(), it) << ": ";
cin >> it->score;
cin.ignore();
}
cout << endl;
}
where it is the iterator that's incremented via ++it from highScores.begin() to just before highScores.end(); then you access the members of the highScores's element "pointed by" it via it->member.
Here's a complete demo.
By the way, considering how much your professor likes void(some_type&) functions (and using namespace std;, if that was not your own idea), I would doubt you have much to learn from him. You better buy a good book.
I would do it like this, also get used to typing std::
Why is "using namespace std;" considered bad practice?
Also be careful with signed/unsigned, be precise about it.
If something can't have a negative value use unsigned types (or size_t)
#include <iostream>
#include <string>
#include <vector>
struct HighScore
{
std::string name;
unsigned int score;
};
// use size_t for sizes (value will always >0)
std::vector<HighScore> GetHighScores(size_t size)
{
std::vector<HighScore> highScores;
std::string points;
for (size_t index = 0; index < size; index++)
{
HighScore score;
std::cout << "Enter the name for score #" << (index + 1) << ": ";
std::cin >> score.name;
std::cout << "Enter the score for score #" << (index + 1) << ": ";
std::cin >> points;
// convert string to int
score.score = static_cast<unsigned int>(std::atoi(points.c_str()));
highScores.push_back(score);
}
std::cout << std::endl;
return highScores;
}
int main()
{
auto highScores = GetHighScores(3);
return 1;
}

Greedy Algorithm for coin change c++

So, I'm creating a coin change algorithm that take a Value N and any number of denomination and if it doesn't have a 1, i have to include 1 automatically. I already did this, but there is a flaw now i have 2 matrix and i need to use 1 of them. Is it possible to rewrite S[i] matrix and still increase the size of array.... Also how can i find the max denomination and the second highest and sooo on till the smallest? Should i just sort it out in an highest to lowest to make it easier or is there a simpler way to look for them one after another?
int main()
{
int N,coin;
bool hasOne;
cout << "Enter the value N to produce: " << endl;
cin >> N;
cout << "Enter number of different coins: " << endl;
cin >> coin;
int *S = new int[coin];
cout << "Enter the denominations to use with a space after it" << endl;
cout << "(1 will be added if necessary): " << endl;
for(int i = 0; i < coin; i++)
{
cin >> S[i];
if(S[i] == 1)
{
hasOne = true;
}
cout << S[i] << " ";
}
cout << endl;
if(!hasOne)
{
int *newS = new int[coin];
for(int i = 0; i < coin; i++)
{
newS[i] = S[i];
newS[coin-1] = 1;
cout << newS[i] << " ";
}
cout << endl;
cout << "1 has been included" << endl;
}
//system("PAUSE");
return 0;
}
You could implement it with std::vector, then you only need to use push_back.
std::sort can be used to sort the denominations into descending order, then it's just a matter of checking whether the last is 1 and adding it if it was missing. (There is a lot of error checking missing in this code, for instance, you should probably check that no denomination is >= 0, since you are using signed integers).
#include <iostream> // for std::cout/std::cin
#include <vector> // for std::vector
#include <algorithm> // for std::sort
int main()
{
std::cout << "Enter the value N to produce:\n";
int N;
std::cin >> N;
std::cout << "Enter the number of different denominations:\n";
size_t denomCount;
std::cin >> denomCount;
std::vector<int> denominations(denomCount);
for (size_t i = 0; i < denomCount; ++i) {
std::cout << "Enter denomination #" << (i + 1) << ":\n";
std::cin >> denominations[i];
}
// sort into descending order.
std::sort(denominations.begin(), denominations.end(),
[](int lhs, int rhs) { return lhs > rhs; });
// if the lowest denom isn't 1... add 1.
if (denominations.back() != 1)
denominations.push_back(1);
for (int coin: denominations) {
int numCoins = N / coin;
N %= coin;
if (numCoins > 0)
std::cout << numCoins << " x " << coin << '\n';
}
return 0;
}
Live demo: http://ideone.com/h2SIHs

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

c++ multidimensional sorting

I have written a basic program that collects student names and answers and automatically scores them. At the end I'd like to sort the scores in descending order with the corresponding names. I understand how to sort the scores but not in combination with the student names. This is what I have so far.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//declare variables
char choice;
string studentName;
vector<char> answers;
vector<string> names;
int getStudents();
int getQuestions();
//calls function to get number of questions
int questions = getQuestions();
//Get answers
for (int i = 0; i < questions; ++i) {
cout << "What is the answer for question " << i + 1 << endl;
cin >> choice;
answers.push_back(choice);
}
//Get number of students
int students = getStudents();
//Get student names
for (int i = 0; i < students; i++) {
cout << "Student " << i + 1 << ", what is your name?" << endl;
cin >> studentName;
names.push_back(studentName);
}
int score = 0;
char studentAnswer;
vector<char> userAnswer;
vector<float> finalScore;
//gets student answers
for (int i = 0; i < students; i++) {
score = 0;
for (int j = 0; j < questions; j++) {
cout << names[i] << ", what is your answer for question " << j + 1 << "?" << endl;
cin >> studentAnswer;
userAnswer.push_back(studentAnswer);
if (userAnswer[i*questions+j] == answers[j])
score = score + 1;
}
finalScore.push_back(score);
}
//outputs scores
std::sort(finalScore.begin(), finalScore.end());
for (int i = 0; i < students; i++) {
cout << names[i] << " scored " << finalScore[i] << " out of " << questions <<
" or " << (finalScore[i] / questions) * 100 << "%" << endl;
}
system("pause");
return 0;
}
//function to get number of questions
int getQuestions()
{
int questions;
cout << "How many questions are there?" << endl;
cin >> questions;
return questions;
}
//function to get number of students
int getStudents()
{
int students;
cout << "How many students are there?" << endl;
cin >> students;
return students;
}
Right now, it sorts the scores in descending orders but the names that are output with the scores are incorrect.
You need to somehow 'connect' student name with his/her score. A very easy and straightforward way is to create a struct, i.e.
typedef struct Student
{
string student_name_;
float student_score_;
} Student;
Next you need to define a Compare function (look here for an example: http://www.cplusplus.com/reference/algorithm/sort/) so that you can use std:sort to sort a vector of Students. Your Compare function could like like this:
bool myCompareFunction ( Student a, Student b)
{
return (a.student_score_ < b.student_score_);
}
To keep the spirit of what you are doing, you can make a vector of pairs, here is a code example:
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
int main()
{
std::vector< std::pair<double,std::string> > my_student_list; // first element is the grade, second is the name
std::pair<double,std::string> student1(2.,"name1"),student2(2.,"name2"),student3(1.,"name3");
my_student_list.push_back(student1);
my_student_list.push_back(student2);
my_student_list.push_back(student3);
std::sort(my_student_list.begin(),my_student_list.end()); // sort by grade
// loop over the vector to print the sorted list
for(std::vector< std::pair<double,std::string> >::iterator iterator = my_student_list.begin(); iterator != my_student_list.end(); iterator++){
// iterator->second is the name, and iterator->first the associated grade
std::cout << iterator->second << " " << iterator->first << std::endl;
}
return 0;
}