Several people are playing a game. Every player has a certain individual number of victories and losses (which might be equal or different). Write a program that prints the name and final result of each of them,.
Note: If there is a player with multiple attempts, the victories and losses are added to the final result.
Input
• Until you receive the string "End", you are given the players’ information in the following order:
- Name: string
- Victories: a positive integer
- Losses: a positive integer
using namespace std;
int main() {
char str[100][20], t[20];
int i, j;
int n;
cin >> n;
int first[100];
int second[100];
for (i = 0; i < n; i++) {
cout << " ";
cin >> str[i];
cin >> first[i];
cin >> second[i];
}
for (i = 1; i < n; i++) {
for (j = 1; j < n; j++) {
if (strcmp(str[j - 1], str[j]) > 0) {
strcpy_s(t, str[j - 1]);
strcpy_s(str[j - 1], str[j]);
strcpy_s(str[j], t);
}
}
}
// cout << "\n Names Sorted in Alphabetical Order : \n\n";
for (i = 0; i < n; i++) {
cout << " ";
cout << str[i] << endl;
cout << first[i] - second[i] << endl;
}
return 0;
}
First, Your choice of data structures is questionable. You essentially have three arrays, side by side by side, that must all be maintained together when modifying the "order" of any one of them. That is the crucial piece of logic missing in your code.
Second, you're utilizing none of the standard C++ library, save for IO operations. Although this can compile, and may even work, you're not fulfilling a key attribute of an arbitrary number of entries. You code assumes the first input is a count of players. Nowhere in the problem description is that assumption validated. You should be reading name,victories,losses as a trio continuously until "End" is read for the name and/or you reach eof on stdin (the latter is assumed but safely so). Dynamic storage is required, and the C++ standard library as a multitude of containers available to make that possible, the most common being std::vector
#include <iostream>
#include <vector>
#include <string>
#include <utility>
int main()
{
std::vector< std::string > names;
std::vector< int > wins;
std::vector< int > losses;
std::string name;
int win;
int loss;
while (std::cin >> name && (name != "End") && std::cin >> win >> loss)
{
names.emplace_back(name);
wins.emplace_back(win);
losses.emplace_back(loss);
}
size_t len = names.size();
while (len-- > 0)
{
for (size_t j = 0; j < len; ++j)
{
if (names[j + 1] < names[j])
{
// swap all three arrays
std::swap(names[j + 1], names[j]);
std::swap(wins[j + 1], wins[j]);
std::swap(losses[j + 1], losses[j]);
}
}
}
std::cout << "Names Sorted in Alphabetical Order:\n";
for (size_t i = 0; i < names.size(); ++i)
{
std::cout << names[i] << '\n';
std::cout << wins[i] - losses[i] << '\n';
}
return 0;
}
Note, this is incredibly non-maintainable. As more and more information is associated with each name (not just wins and losses, but perhaps home address, telephone number, playing style or position etc.) maintaining yet more arrays becomes a nightmare. Rather, you opt for an object to host all player information, and single container that holds instances of that object. No doubt you'll be learning more on that in your studies.
But in the meantime, the code above complies with the problem statement, while addressing the key piece of logic missing in your posted code. If you're going to swap names during sorting, you have to swap win/loss records as well, so the player in some arbitrary position n has their wins/losses come along for the ride.
No wonder that someone will whine that it is a homework comment and not to help.
AJod Accrd i think that you need to do a public class and then do a map of string and pair of 2 integers
Related
I have an array and I want to subtract each of the elements consecutively, ex: {1,2,3,4,5}, and it will result to -13 which is by 1-2-3-4-5.
But I don't declare or make those numbers fixed as they're taken from the input (user). I only make it like, int array[100] to declare the size.
Then, to get the inputs, I use the for loop and insert them to the array. Let's say first input is 10, then array[0] must be 10 and so on.
The problem is, how do I subtract them? I have two options:
The first element of the array (array[0]) will subtract the next element (array[1]) right after the user input the second element, and the result (let's say it's int x) will subtract the next element (array[2]) after the user input it and so on.
I'll have the user input all the numbers first, then subtract them one by one automatically using a loop (or any idea?) *These elements thing refer to the numbers the user input.
Question: How do you solve this problem?
(This program will let the user input for as much as they want until they type count. Frankly speaking, yeah I know it's quite absurd to see one typing words in the middle of inputting numbers, but in this case, just how can you do it?)
Thanks.
Let's see my code below of how I insert the user input into the array.
string input[100];
int arrayInput[100];
int x = 0;
for (int i = 0; i >= 0; i++) //which this will run until the user input 'count'
{
cout << "Number " << i+1 << ": ";
cin >> input[i];
arrayInput[i] = atoi(input[i].c_str());
...
//code to subtract them, and final answer will be in int x
...
if (input[i] == "count")
{
cout << "Result: " << x << endl;
}
}
You can/should use a dynamic sized container like std::vector as shown below:
#include <iostream>
#include <vector>
int main()
{
int n = 0;
//ask user how many input he/she wants to give
std::cout << "How many elements do you want to enter: ";
std::cin >> n;
std::vector<int> vec(n); //create a vector of size n
int resultOfSubtraction = 0;
//take input from user
for(int i = 0 ; i < n ; ++i)
{
std::cin >> vec.at(i);
if(i != 0)
{
resultOfSubtraction-= vec.at(i);
}
else
{
resultOfSubtraction = vec.at(i);
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}
Execute the program here.
If you want a string to end the loop then you can use:
#include <iostream>
#include <vector>
#include <sstream>
int main()
{
std::vector<int> vec;
int resultOfSubtraction = 0, i = 0;
std::string endLoopString = "count";
std::string inputString;
int number = 0;
//take input from user
while((std::getline(std::cin, inputString)) && (inputString!=endLoopString))
{
std::istringstream ss(inputString);
if(ss >> number)
{
vec.push_back(number);
if(i == 0)
{
resultOfSubtraction = number;
}
else
{
resultOfSubtraction-= number;
}
++i;
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}
I have class City with following private data: name of city, width,length and height of the city. I have to make dynamic array, which is inserted by constructor by default- City(),when the programs starts.Then the program uses method output() and prints inserted array of cities.
I should use bubble sort to sort the cities by their length. And when this is done, the program should show the sorted cities in increasing lengths.
The problem is that my data are in private(in public everything works excellent but principle of capsulation is violated!) so I can't do bubble sort.
I tried to do another dynamic array of type double double Lengths[n], which content is lengths of first array. Then I do sorting, but program prints only sorted lengths and this is not my goal.
I should print the names of cities sorted by their lengths.
Code:
class City{
private: char *name;
double width;
double length;
double height;
public:void Output();
City();
~City();
double GetLength()
{
return length;
}
double GetWidth(){ return width; }
double GetHeight(){ return height; }
char GetName(){ return *name; }
};
City::City()
{
char ime[20];
cout << "Name= ";
cin >> ime;
name = new char[strlen(ime) + 1];
for (int i = 0; i <=strlen(ime); i++)
name[i] = ime[i];
cout << "Width= ";
cin >> width;
cout << "Length= ";
cin >> length;
cout << "Height= ";
cin >> height;
}
void City::Output()
{
cout << "Name is: " << name << endl;
cout << " Width is: " << width <<" deg"<< endl;;
cout << " Length is: " << length << " deg"<<endl;
cout << " Height is: " << height <<" m"<<endl;
return;
}
City::~City()
{
cout << " " << endl;
cout << "Destructor of City!" << endl;
delete[] name;
}
int main()
{
//City town;
//town.Input();
//town.Output();
int n;
City *mA;
cout << "Input number of cities: " << endl;
cin >> n;
mA = new City[n];
for (int j = 0; j < n; j++)
{
mA[j].Output();
}
cout << "Cities from west to east, sorted by their length" << endl;
double *Lengths = new double[n];
for (int j = 0; j < n; j++)
{
Lengths[j] = mA[j].GetLength();
}
int k = 0;//counter
double max = Lengths[0];
for (int j = 1; j < n; j++)
{
if (Lengths[j - 1] >Lengths[j])
{
max = Lengths[j - 1];
Lengths[j - 1] = Lengths[j];
Lengths[j] = max;
}
}
for (int j = 0; j < n; j++)//cycle for output
{
mA[j].Output();
}
delete[]mA;
return 0;
}
As I can't quite comment on your response, I will give you a few bits of advice. First in the line of:
Array[j]=mA[j].GetName() ;
You have a random space which may be a copy change and relatively minor but for reading purposes that is wrong.
Second your naming conventions are really something you should work on. I should be able to read a variable and understand what it means but instead I struggle to understand what a variable named mA means.
Third your else clause does nothing literally. Your not moving any parts of the array if that is your intention my saying this:
mA[j+1];
you are simply targeting the element in the array that is above the iteration. I see you stuck with your idea of making something similar to a parallel array for the bubble sort, and that is fine but you lack any action in the first loop.
This is not bubble sort what so ever as you are simply going through each iteration and checking if the element in Lengths is equal in length to the element in mA and then storing that element in array but your else statement does nothing.
Your loop should look similar to something like this but I'm gonna get rid of the character array and the extra array for some reason as it is unnecessary and lets say you start out with an array of your objects:
if(myObjects[i].GetLength() > myObjects[i+1].GetLength()) //Shortest to longest name or vice versa?
{
//Store myObject[i] in temp spot
//myObject[i] = myObject[i+1]
//myObject[i+1] = temp Storage
}
This will give you a bubble sort of the objects on the first round. Of course your going to have to find out how to iterate through the array in loop to verify all of the elements have been sorted correctly as this will of course take many iterations for bubble sort.
I don't see a direct question but I can assume majority of the question by your story. You have multiple options on how to solve this case. One of the simple ways to solve this is create a function within the object that allows you to get the length of a member of an object for example in your case it would be name of city.
Create a method inside the object that you can call to return a private method's length. Create a loop that calls this method and checks each element side by side until you can't refine it any longer. Is there a specific reason your using char instead of string for name?
I'm not entirely sure of what you're asking.
However, from what I can tell your main issue is that you can't sort because you're trying to compare two private variables from two objects.
If the objects are placed into an Array of type city, you can bubblesort by length however you would be required to use the getters in order to reference the variables that are private during sorting.
For example (not exact syntax)
if(cityArray[0].getLength() < cityArray[1].getLength())
{
//Do Something
}
Trying to reverse the order of the characters input. I'm getting really close but no cigar.
#include <iostream>
using namespace std;
const int MAX = 10;
int main()
{
char a[MAX], next;
int index = 0;
cout << "Please enter in up to 10 letters ending with a period: " << endl;
cin >> next;
while((next != '.') && (index < 10))
{
a[index] = next;
index++;
cin >> next;
//cout << " " << next << endl;
}
int numbers_used = index;
for(index = 0; index <= numbers_used; index++)
{
a[index] = a[numbers_used -1];
numbers_used--;
cout << a[index] << " " << endl;
}
}
I'm getting everything but the last switch and even though my code is not as clean I'm failing to see where I'm going wrong.
The book code is:
for(index = numbers_used -1; index >= 0; index--)
cout<<a[index];
cout<< endl;
and why is it index = numbers_used - 1 ?? Since numbers_used was set to index and index was initialized at 0 and not 1 wouldn't I want to run the loop "numbers_used" amount of times? What am I missing?
Try this:
char* flip(char* str, int len) {
for(int x=0; x<(len/2); x++) {
swap(str[x], str[len-x-1]);
}
return str;
}
As of right now, after you get to the middle of the string, you'll have overwritten the values that you would need to copy to the second half. With a string like "FooBarBiz", your code will produce the following over iterations (I've put spaces in to try and make things clearer):
1: FooBarBiz
2: z ooBarBiz
3: zi oBarBiz
4: ziB BarBiz
5: ziBr arBiz
6: ziBra rBiz
7: ziBrar Biz
...
The code I posted however, uses the c++ swap function to swap the complimentary values, that way there are no lost values (we're not doing any overwriting), and you won't need to store the whole string in a placeholder variable. Does this make sense?
If you want to reverse the list you have to start from the last element and decrease the index .
You can approach this in at least two different ways. You can reverse the order of the string and then print, or you can leave the original string unmodified and simply print in reverse. I'd recommend the latter approach, in which case all you'd need to do is to change your last for loop to this:
for(index = 0; index < numbers_used; index++)
{
cout << a[numbers_used-index-1] << " " << endl;
}
Wouldn't it be easier this way ?
#include<iostream>
#include<string>
using namespace std;
const int MAX = 5;
int main()
{
char a[MAX], next;
int index = 0;
bool period = false;
cout << "Please enter in up to 10 letters ending with a period: " << endl;
for(int i = 0; i < MAX && !period; i++)
{
cin >> next;
if(next != '.')
{
a[i] = next; // put the value into the array
index++;
}
else
period = true;
}
for(int i = index - 1; i >= 0 ; i--)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
The problem can be solved by using the iterators from the standard library. The BidirectionalIterator as for example offered by std::string, std::list or std::vector can be traversed in both directions.
Using a std::string the solution could be:
#include <iostream>
#include <string>
using namespace std;
int main(int, char**) {
char n = 0;
string a;
while (n != '.' && a.size() < 10) {
cin >> n;
if (n != '.') {
a.push_back(n);
}
}
for (string::reverse_iterator it = a.rbegin(); it != a.rend(); ++it) {
cout << *it << endl;
}
}
I will start by saying: use std::string instead of C-style strings - it's universally less messy and more flexible.
Still, let's go with C-style strings since that's how you are attempting to do it and apparently your textbook also.
I won't comment on the way the user input is read, because I'm not sure if it's copied from the textbook (yikes!!) or you've done it yourself either way I find it to be pointless and wrong because it can lead to several problems. Note that the given book solution only prints out the characters in the reversed order and doesn't reverse the character array itself. You are apparently trying to reverse it.
Your solution is decrementing the numbers_used variable inside the for loop itself. This is a very bad idea since that variable is used in the conditional statement of the for loop. This means the loop will stop before it has iterated over the whole array. Even if the loop worked properly you still wouldn't have reversed the array since once this line executes
a[index] = a[numbers_used -1];
the original value of a[index] is overwritten and forgotten.
I'll try and write a simple solution to reverse a character array for a beginner:
#include <iostream>
#include <cstring> //getline, strlen
using namespace std;
const int MAX_LETTERS = 10;
int main() {
char a[MAX_LETTERS + 1]; //since it's zero terminated
cout << "Enter at most " << MAX_LETTERS << "characters (anything over " <<
MAX_LETTERS << " will be truncated):\n";
cin.getline(a, MAX_LETTERS + 1);
int length = strlen(a); //returns length of input
int last_char = length - 1;
//reverse array
for (int i = 0; i < length / 2; i++) {
char temp = a[i];
a[i] = a[last_char];
a[last_char] = temp;
last_char--;
}
//print array
for (int i = 0; i < length; i++)
cout << a[i];
return 0;
}
Read this tutorial on C style strings, it will help you a lot.
The last for loop in your code is
int numbers_used = index;
for(index = 0; index <= numbers_used; index++)
{
a[index] = a[numbers_used -1];
numbers_used--;
cout << a[index] << " " << endl;
}
If we consider 10 letters abcdefghij and according to your code the numbers_used=10after first loop.So in second loop
//In for loop
//index=0
a[index]=a[numbers_used-1]; // a[0]=a[9] => a[0]=j
numbers_used--; //numbers_used=9;
//index=1
a[index]=a[numbers_used-1]; //a[1]=a[8] => a[1]=i
numbers_used--; //numbers_used=8;
//index=2
a[index]=a[numbers_used-1]; //a[2]=a[7] => a[1]=h
numbers_used--; //numbers_used=7;
//index=3
a[index]=a[numbers_used-1]; //a[3]=a[6] => a[1]=g
numbers_used--; //numbers_used=6;
//index=4
a[index]=a[numbers_used-1]; //a[4]=a[5] => a[4]=f
numbers_used--; //numbers_used=5;
//index=5
a[index]=a[numbers_used-1]; //a[5]=a[5] => a[5]=e
numbers_used--; //numbers_used=4;
// index=6 and numbers_used becomes 4 => index <= numbers_used condition is violated
so you will out of for loop.
This is why u cant get through. And in the second code i,e in the Book.
for(index = numbers_used -1; index >= 0; index--)
cout<<a[index];
cout<< endl;
The numbers_used value is 10 but a[9] is the last value in the array so index is assigned to numbers_used-1. so that you can print from a[9] to a[0].
I present to you all a program I'm working on for my college programming course. I still have a little ways to go before it completely meets my assignment's requirements, but I've gotten a basic draft of the program error-free (supposedly) and it appears to run… but then it suddenly kicks me into Xcode's debugger and gives me:
Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)
Here's the command line output, up until it kicks me out:
-----------------------
Quarterly_sales_taxator
-----------------------
How many company divisions will we be dealing with? 2
Am I correct in assuming that there are 4 sales quarters? yes
Please enter the sales Company Division #1 brought in for Sales Quarter #1 20
(lldb)
Here's my code:
//
// quarterly_sales_taxator.cpp
// Ch. 7 program #7
//
// Created by John Doe on 11/27/12.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
void read_company_divisions_and_sales_quarters(double **, int, int);
//void write_company_divisions_and_sales_quarters_to_array(double **, int, int); // This will be used later on to read data from a file.
void display_quarterly_sales_array(double **, int, int);
string temp; // A global temporary placeholder variable; I use this several times.
int main()
{
int COMPANY_DIVISIONS,
SALES_QUARTERS = 4;
double **quarterly_sales_form;
cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";
cout << "\nHow many company divisions will we be dealing with? ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
{
cout << "\n\n------"
<< "\nError:"
<< "\n------"
<< "\n\nYou have entered an invalid choice."
<< "\nPlease type a number greater than zero. ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
}
cout << "\n\nAm I correct in assuming that there are 4 sales quarters? ";
getline(cin, temp);
// Convert to uppercase.
for (int count = 0; count < temp.length(); count ++)
{
temp[count] = toupper(temp[count]);
}
if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
{
cout << "\nOk, then how many sales quarters are we dealing with? ";
getline(cin, temp);
stringstream(temp)>>SALES_QUARTERS;
}
cout << endl << endl;
// This sets up the 2d array.
quarterly_sales_form = new double *[COMPANY_DIVISIONS];
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS); // I'll add this feature later.
cout << "\n\nHere's what you entered:\n\n";
display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// Since we used a series of pointers, we need to free the allocated space back up.
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ delete[] quarterly_sales_form[COMPANY_DIVISIONS]; }
delete[] quarterly_sales_form;
return 0;
}
/*############################################
# read_company_divisions_and_sales_quarters #
############################################*/
void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < QUARTERS; count++)
{
for (int index = 0; index < DIVISIONS; index++)
{
cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << " ";
getline(cin, temp);
stringstream(temp) >> array[count][index];
}
}
}
/*################################
# display_quarterly_sales_array #
#################################*/
void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < DIVISIONS; count++)
{
cout << "\nCompany division #" << count+1 << ":\n";
for (int index = 0; index < QUARTERS; index++)
{ cout << array[count][index] << ", "; }
}
}
Can some kind soul please tell me what I'm doing wrong?
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
In this line, COMPANY_DIVISIONS should be count.
In addition to what Dan Hulme said, it seems this line
stringstream(temp) >> array[count][index];
should really be
std::istringstream(temp) >> std::skipws >> array[index][count];
In addition to using std::istringstream rather than std::stringstream and making sure that an lvalue is at hand, which isn't strictly needed until the type read becomes more interesting, this also reverses the indices: index runs over COMPANY_DIVISIONS and count over SALES_QUARTERS.
The real question is, of course: Who hands out assignments like this? Pointer manipulations and allocations are best left to low-level library writers. This is C++ not C: we can and should use abstractions. Getting this code exception safe is a major challenge and there is no point in teaching people how to write broken (e.g. exception unsafe) code.
How can I write a program that reads in, a collection of characters from the key board and outputs them to the console. Data is input at random, but output selectively. Only unique characters are displayed at the console. Therefore, every character should be displayed once, no matter how many times it appears in the array.
For example, if an array
Char letterArray[ ] = {B,C,C,X,Y,U,U,U};
The output should be:
B,C,X,Y,U
This is what I have done so far...
char myArray [500];
int count = 0;
int entered = 0;
char num;
while (entered < 8)
{
cout << "\nEnter a Character:";
cin >> num;
bool duplicate = false;
entered++;
for (int i = 0; i < 8; i++)
{
if (myArray[i] == num)
duplicate=true;
}
if (!duplicate)
{
myArray[count] = num;
count++;
} // end if
else
cout << num << " character has already been entered\n\n";
// prints the list of values
cout<<"The final Array Contains:\n";
for (int i = 0; i < count; i++)
{
cout << myArray[i] << " ";
}
}
I believe you could make use of std::set<>.
"Sets are a kind of associative container that stores unique elements <...> elements in a set are always sorted from lower to higher following a specific strict weak ordering criterion set"
Looking through your code...
char myArray [500];
Why 500? You never use more than 8.
char num;
Confusing naming. Most programmers would expect a variable named num to be a numeric type (e.g. int or float).
while (entered < 8)
Consider replacing 8 with a constant (e.g. const int kMaxEntered = 8;).
cin >> num;
cin might be line-buffered; i.e. it does nothing until a whole line is entered.
for (int i = 0; i < 8; i++)
{
if (myArray[i] == num)
duplicate=true;
}
You're accessing uninitialized elements of myArray. Hint: your loop size should not be 8.
Consider using continue; if you find a duplicate.
if (!duplicate)
{
myArray[count] = num;
count++;
} // end if
else
cout << num << " character has already been entered\n\n";
Your // end if comment is incorrect. The if isn't ended until the else is done.
You may want to add braces around the else clause, or remove the braces from the if clause by combining its two lines into the one-line myArray[count++] = num;.
// prints the list of values
cout<<"The final Array Contains:\n";
for (int i = 0; i < count; i++)
{
cout << myArray[i] << " ";
}
You're printing the list every time you get a single input?
Don't use \n in text to cout unless you specifically want to micromanage buffering. Instead, use endl. Also, always put spaces around binary operators like << and don't randomly capitalize words:
cout << "The final array contains:" << endl;
for (int i = 0; i < count; i++)
cout << myArray[i] << " ";
cout << endl;
It would be much more efficient to create an array of size 128 (assuming you are dealing with ASCII) that is initialized with false. Every time you get a character, check its ASCII value and if the array is true on that value you don't print it. After that, update the value of the array on the character value to true. Something like:
bool *seenArray = new bool[128]();
void onkey(char input) {
if(((int)input) < 0) return;
if (!seenArray[(int)input]) {
myArray[count] = input;
count++;
seenArray[(int)input] = true;
}
}