A given file contains pairs of . Then take a toss-up two-digit number (called X), and compute the win/loss amount. The win/loss rule is if the input number matches X, then it’s a win and the winning total is (amount * 70); otherwise, it’s a loss of (-amount).
For example: [ticket.txt]
09 10
13 15
25 21
If the toss-up number is 09, the win/loss amount of the ticket is (10 * 70 - 15 - 21 = 664)
If the toss-up number is 42, the win/loss amount of the ticket is (-10 - 15 - 21 = -46).
While reading file by arrays has a fixed size. What I mean is that what if the file ticket.txt doesn't have specific size. Can someone help me to change reading file by array to vector or something else doesn't have fixed size.
For example: [ticket.txt]
09 10
13 15
25 21
.. ..
#include <iostream>
#include <fstream>
using namespace std;
int line1[100]; // array that can hold 100 numbers for 1st column
int line2[100]; // array that can hold 100 numbers for 2nd column
int main()
{
int winNum, winAmount = 0, lostAmount = 0, result = 0;
int num = 0; // num start at 0
ifstream inFile;
inFile.open("Ticket.txt"); //open File
if (inFile.fail())
{
cout << "Fail to open the file" << endl;
return 1;
}
int myArray[3][2];
for(int i = 0; i < 3; i++)
for(int j = 0; j < 2; j++)
inFile >> myArray[i][j];
cout << "Numbers from File: " << endl;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 2; j++)
{
cout << myArray[i][j] << " ";
}
cout << "\n";
}
cout << endl;
cout << "Enter the toss-up number: "; // enter the win number
cin >> winNum;
for(int i = 0; i< 3;i++)
{
if (myArray[i][0] == winNum)
{
winAmount = myArray[i][1] * 70; // number user choose = win number, winAmount = winAmount * 70 - lostAmount
}
else
{
lostAmount = lostAmount + myArray[i][1]; //number user choose != win number, the amount will be -lost amounts
}
}
result = winAmount - lostAmount;
cout << result;
cout << endl << endl;
system("pause");
return 0;
}
There are a bunch of different ways to approach this problem.
One could make a vector of vectors
std::vector<std::vector<int>> myArray;
but this is pretty wasteful. Only the inner dimension is variable in size, so a quick improvement is
std::vector<std::array<int, 2>> myArray;
Loading myArray can be pretty simple, depending on how much verification you want to include. Here it is with minimal verification:
int number,amount;
while (inFile >> number >> amount)
{
myArray.push_back({number,amount});
}
This will loop until two ints can't be read, be it because of the end of the file or garbage in the file. It is also easily fooled by a file with the worn number of columns . Better approaches use std::getline to get whole lines and make sure exactly two valid numbers and nothing else is on each line.
The rest of your code is unchanged.
But there may be a better way to do this, Consider
a) The loss amount never changes. You can precompute it and eliminate the loop in the event of a loss.
b) Extending on that, you can eliminate part of the loop on a win. The loss amount contains the winning number use the loss amount minus the winning amount. In other words,
winnings = amount * 70 - (loss - amount)
Which is the same as
winnings = amount * 70 - loss + amount
or
winnings = amount * 71 - loss
So we can stop looking as soon as we find a win and only do one calculation.
c) We can eliminate any need for a look-up loop with a std::map.
Reading in the file into a std::map is similar:
std::map<int, int> myMap;
int number,amount;
int loss = 0;
while (inFile >> number >> amount)
{
myMap[number] = amount; // map the amount to the number
loss += amount;
}
and look-up is something like
int result = 0;
auto found = myMap.find(winNum); // look in the map for a number
if (found != myMap.end()) // number is in the map
{
result = 71* found->second; // take the winnings plus one extra to counterbalance
// number's addition to the losses
}
result -= loss; //remove the loss
The calculation loop is completely eliminated and less code is almost always better. Code that's not there has zero bugs. Unless it not being there IS a bug, but that's a different problem.
Note: For small files this approach will be SLOWER. std::map has a much lower time complexity than iterating a std::vector, but each of those iterations it has to perform can be much more expensive.
Documentation on std::array
Documentation on std::vector
Documentation on std::map
Related
I am needing to print out all pairs of numbers from each line read in from a text document. A sample text document would be:
6 8
1 3 5
2 3 4
3 6 5
7 6 8
4 6
7 5
Where the first line is the number of nets (6) and the number of cells (8) for a hypergraph. The rest of the lines are the cells that are in the net. So net 1 consists of cells 1, 3, and 5, net 2 consists of cells 2, 3, and 4 and so on. In order to turn this netlist into an actual graph I need to go through each line and basically take all combinations of the numbers on each line. So after reading in the first net I would like to be able to make a graph with (1,3), (1,5), and (3,5) and then go down the netlist and add to the graph. So far I am able to read everything in from the text file and print out the individual cells that I put into a 2D array. Here is my code for that:
int main() {
ifstream infileHGR; // set stream for hypergraph text file
string inputFileName = "structP.hgr"; // input hypergraph filename here
infileHGR.open(inputFileName, ios::in);
clock_t start = clock(); // start clock
string line;
string data[2]; // initialize data array to take in # of nets and # of cells
int nets = 0;
int cells = 0;
// Reads in the first line of the text file to get # for nets and cells
getline(infileHGR, line);
stringstream ssin(line);
int i = 0;
while (ssin.good() && i < 2) { // error checking to make sure first line is correct format
ssin >> data[i];
i++;
}
nets = atoi(data[0].c_str()); // set first number to number of nets
cells = atoi(data[1].c_str()); // set second number to number of cells
freopen("output.txt", "w", stdout); // writes outptut to text file
// TESTING PURPOSES
cout << "Number of nets = " << nets << endl;
cout << "Number of cells = " << cells << endl;
// while loop to go through rest of the hgr file to make hypergraph (starts at line 2)
string str;
int count = 1; // counter for nets
while (infileHGR.good()) {
getline(infileHGR, str);
stringstream in(str);
int i = 0;
// have the line in str
int n = 1; // start at 1, spaces + 1 = number of nodes per net
for (int i = 0; i < str.length(); ++i) {
if (str.at(i) == ' ') {
n++; // n is number of cells in the net
}
}
// testing
//cout << "str = " << str << endl;
//cout << "n = " << n << endl;
int number;
vector<vector<int> > netList;
vector<int> temp;
while (in >> number){
temp.push_back(number);
}
netList.push_back(temp);
//printNetList(temp); // test to see if info is being put into the vectors
// loop through the 2d vector
for (const auto& inner : netList) {
cout << "net " << count << " = "; //TESTING PURPOSES
for (const auto& item : inner) {
cout << item << " ";
}
count = count + 1;
}
cout << endl;
}
clock_t stop = clock(); // end clock
infileHGR.close();
double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
printf("Time elapsed in ms: %f", elapsed);
system("pause"); //for original testing
return 0;
}
I used vectors because every input file will be of different size, and some contain a lot of nets, and some nets have up to 20 cells in them. I need help with getting all pairs (coordinates) from the netlist and printing them out to show all of them. I have messed around with the for loops a lot but can't seem to get something that works. Any help would be greatly appreciated, and just ask if I need to include anything else. Thank you!
If you're looking to print out all of the possible indexes from an array. You are looking in the right direction. You can do it with for loops, and I actually had this issue a bit back for an assignment. Take a look at this, it should return all possible indexes:
int b, c = 0;
int userIndex_A;
int userIndex_B;
cin >> userIndex_A;
cin >> userIndex_B;
//This is so you can have variable array lengths
int Arr[userIndex_A][userIndex_B];
for(int a = 0; c < 10; a++){
//The reason I put c in the for loop, to tell it when to stop, is because when c is equal to 10, that's the last index being paired
cout << "Array Index: "<< b << ", "<< c << endl;
if(b == (userIndex_A - 1)){
//userIndex-A is the array length, but 10 doesn't exist, so subtract 1
b = 0;
c++;
//if b is equal to max index value entered, set it to zero and add one to c. You only add one to c when you want to start with the next set of index.
}
b++;
//after each loop, increment the variables
}
This also works for 3D and 4D arrays too, just add more variables to increment each loop and set up for loops to reset the variable once it reachs the respective max array index length.
Looking at your example,
for each line
for i = 1 to N-1th element
for j = i+1 to Nth element
print (i,j)
I'll post my answer here because I was able to figure it out thanks to some suggestions. Also thank you for all the feedback on the rest of the code, I have definitely made it better since the original post. My for loop though for looping through the 2D vector and printing out all of the pairs is this (you can just ignore the weight variable being output):
for (vector<vector<int>> ::iterator i = netList.begin(); i != netList.end(); ++i) {
for (vector<int> ::iterator j = temp.begin(); j != temp.end() - 1; ++j) {
for (auto k = temp.begin() + 1; k != temp.end(); ++k) {
if (*j != *k) {
cout << *j << " " << *k << " " << weight << endl;
}
}
}
}
I want the program to read my file. I want to count all the numbers in the document that are greater than 175 and that are even using a switch statement. Or is there any better way to do it? Also wanting to know where I can get help with learning C++ since I am new to this? This is what I came up with but my program seems to not execute. This part of a bigger coding program. I want to know if it is possible to create multiple commands in the switch statement. I need help with case 0 on switch(num%2).
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main ()
{ //Listing all my variables
int num;
double even;
int evencount = 0;
int evencountext = 0;
double big;
int bigcount = 0;
double sm;
int smcount = 0;
double odd;
int oddcount = 0;
double small;
double large;
double average;
double total;
int amount = 0;
string filename;
ifstream inFile; //Input and output data from a file
ofstream outFile;
inFile.open("integers.dat"); //Open the integers.dat
if (!inFile) //Closes if the program does not exist.
{
cout << "No File Found! Closing Program." << endl;
return 1;
}
cout << "Welcome to Wake's Integer Processing Agency \n" << endl; //First line of output
cout << "What is the name of your file? "; //Get the name of the file from user
cin >> filename;
cout << endl;
inFile >> num; // Get the first number from the file
large = num; // Copy the number to the large and small variables to give the number something
small = num; // to compare them to.
while (inFile) //Main loop designed to grab numbers continuosly until the file ends.
{
switch (num % 2) //This switch divides the each number in the file by two and examines the remainder
{
case 0: // If the remainder is zero, this means the number is even
evencount++; // Increase the counter for even by one
if(num >= 175)
{evencountext++;};
even = even + num; // And the even number to the variable for total even numbers
break;
case 1: // If remainder is positive or negative one, this means the number is odd
case -1:
oddcount++; // Increase total odd numbers by one
odd = odd + num; // Add the odd number to the variable for total odd numbers
}
cout << evencountext<< endl;
cout << "The sum of the odd integers is " << odd << endl;
inFile.close(); //close the integers.dat file
return 0; //close program
}
}
It is better to use if statement remainder could be anything
if (num % 2 == 0){ // If the remainder is zero, this means the number is even
evencount++; // Increase the counter for even by one
if(num >= 175){
evencountext++;
even = even + num; // And the even number to the variable for total even numbers
}
}else{ // If remainder is not zero, this means the number is odd
oddcount++; // Increase total odd numbers by one
odd = odd + num; // Add the odd number to the variable for total odd numbers
}
Switches and if/else are flow control tools. If/else statements evaluate true/false, whereas switches require integer inputs and tests it against other values; uniformly.
Since you want to run multiple tests per data, I recommend that you store the data acquired into a (temporary) variable so you apply whatever multiple tests you need.
Like others have posted you should use if statements when testing for truths, and switches when testing for matches.
As for tutorials:
My default two recommended:
Tutorial spot:
https://www.tutorialspoint.com/cplusplus/cpp_basic_syntax.htm
CPlusPlus:
http://www.cplusplus.com/doc/tutorial/program_structure/
Code relative to original post:
#include <iostream>//Used for c++ Standard I/O stream
#include <fstream>//Used for c++ File I/O stream
//using namespace std;//Adding this will no longer require you to type any std::
//using std::cout;//Adding this will no longer require you to type std:: in front of cout
//using std::cin;//Adding this will no longer require you to type std:: in front of cin
//using std::fstream; " " "
int main()//Main Function:
{
//Declare and initialize fstream for input operations
std::fstream fs ("file.txt", std::fstream::in);//Open file for reading
//Declare integer variables and provide default values for accumulators/totals.
int large, small, num, even = 0, odd = 0, evenSum = 0, oddSum = 0;
//Declare boolean to test against first run; embedded initialization within loop.
bool first = true;
while(fs >> num) {//DATA stored into variable num.
//Print the number out for debugging (visual reading without debugger).
std::cout<<"The number: "<<num<<std::endl;
//Initialize our smallest number and largest number if not done so already.
if(first) {//Only occurs the first run
first = false;//Disables this test from here on.
small = large = num;
}
//Test if the number is larger than our largest.
if(num > large) {
large = num;
}
//Test if the number is smaller than our smallest.
if(num < small) {
small = num;
}
//Test if the number is 0 or 1. (0 and 1 are false and true, but not really).
if(num%2 == 0) {//If even:
++even;//Increment counter PRE
evenSum+=num;//Accumulate the total even values.
}else {//Else, were assuming it is odd (without having to check again).
odd++;//Increment counter POS; doesn't matter here
//but it does matter if on the stack.
oddSum+=num;//Accumulate the total odd values.
}
}//The end of the while loop. It retests the loop until satisfied.
//In a PRE loop it would leave the loop when false occurs.
//Make sure to always close the file after you're done using it.
fs.close();
//Printing the data:
std::cout<<"Number of even numbers: "<<even<<std::endl;
std::cout<<"Number of odd numbers: "<<odd<<std::endl;
std::cout<<"Sum of even numbers: "<<evenSum<<std::endl;
std::cout<<"Sum of odd numbers: "<<oddSum<<std::endl;
std::cout<<"Largest number: "<<large<<std::endl;
std::cout<<"Smallest number: "<<small<<std::endl;
//std::end produces newline and does some sub-procedure in clearing buffers.
return 0;
}
Sample Output:
The number: 123
The number: 456
The number: 222
The number: 21
The number: 1
The number: 50
The number: 22
Number of even numbers: 4
Number of odd numbers: 3
Sum of even numbers: 750
Sum of odd numbers: 145
Largest number: 456
Smallest number: 1
Sample Input:
123 456 222
21
1
50
22 a
d
55
Can someone please look at this code and help me figure out what's wrong?
#include <iostream>
#include <vector>
using namespace std;
int numExercise;
cout << "Enter num exercises: ";
cin >> numExercise;
vector <float> weight;
float sumWeight = 0;
while(sumWeight != 1)
{
// Loop to assign a weighted value to each exercise.
for ( int i = 0; i < numExercise; i++ )
{
float weightEntered;
cout << "\n Assignment " << i + 1 << " : ";
cin >> weightEntered;
//Divide percentage by 100 to get decimals.
weightEntered /= 100;
//Send the data back to the vector.
weight.push_back( weightEntered );
}
// Loop to error check if the total weights isn't 100.
for ( int i = 0; i < numExercise; i++ )
{
sumWeight += weight[i];
}
cout << sumWeight << endl;
sumWeight = 0;
//if ( sumWeight != 1 )
cout << "\n\t\tError, total weights should be 100" << endl;
}
So in this code I'm entering a certain amount of assignments and the weights per assignment have to be over 100%... for example enter 3 assignments and each weight is 30, 30, 40. After the weight is entered the code divides each weight by 100 to get decimal values (I'm using that in the rest of my code to calculate something else).
The issue is that I'm trying to make sure that whatever the user enters add up to 100 otherwise they have to enter the numbers again. When I run this loop and enter the wrong numbers it asks me to enter them again but it doesn't go through the sum of the weights entered the second time, so the number displayed is still the first sum. What am I doing wrong??
You are using vector to store the weights,
Let say for three assignments, you entered 30,30,30. Now vector becomes { 30,30,30 } and you are summing over this vector from 0 to 2 index.
In next time, you entered 20,20,40. Now vector becomes {30,30,30,20,20,40} and you are summing over this vector again from 0 to 2 index.
You can solve your problem by using insert rather than push_back
I'm beginning with C++. The question is: to write a program to input 20 natural numbers and output the total number of odd numbers inputted using while loop.
Although the logic behind this is quite simple, i.e. to check whether the number is divisible by 2 or not. If no, then it is an odd number.
But, what bothers me is, do I have to specifically assign 20 variables for the user to input 20 numbers?
So, instead of writing cin>>a>>b>>c>>d>>.. 20 variables, can something be done to reduce all this calling of 20 variables, and in cases like accepting 50 numbers?
Q. Count total no of odd integer.
A.
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int n,odd=0;
cout<<"Number of input's\n";
cin>>n;
while(n-->0)
{
int y;
cin>>y;
if(y &1)
{
odd+=1;
}
}
cout<<"Odd numbers are "<<odd;
return 0;
}
You can process the input number one by one.
int i = 0; // variable for loop control
int num_of_odds = 0; // variable for output
while (i < 20) {
int a;
cin >> a;
if (a % 2 == 1) num_of_odds++;
i++;
}
cout << "there are " << num_of_odds << " odd number(s)." << endl;
If you do really want to save all the input numbers, you can use an array.
int i = 0; // variable for loop control
int a[20]; // array to store all the numbers
int num_of_odds = 0; // variable for output
while (i < 20) {
cin >> a[i];
i++;
}
i = 0;
while (i < 20) {
if (a[i] % 2 == 1) num_of_odds++;
i++;
}
cout << "there are " << num_of_odds << " odd number(s)." << endl;
Actually, you can also combine the two while-loop just like the first example.
Take one input and then process it and then after take another intput and so on.
int n= 20; // number of input
int oddnum= 0; //number of odd number
int input;
for (int i = 0; i < n; i ++){
cin >> input;
if (input % 2 == 1) oddnum++;
}
cout << "Number of odd numbers :"<<oddnum << "\n";
Just started studying C++ for a couple weeks now, and been running through some exercises. Though I am stuck on trying to return the array name which is holding the highest number in the array. For example, I made an array for 10 people, for each person I am having them enter the number of pancakes they ate, now I want to return the person who ate the most pancakes. just not sure how to do it. It falls apart at the second if statement.
int main()
{
int pancakes[9] = {0,0,0,0,0,0,0,0,0};
int max = pancakes[0];
int i;
int p;
for (int x=0; x<=9; x++)
{
cout << "Enter number " << endl;
cin >> i;
pancakes[x] = i;
if(i > max)
max = i;
pancakes[x] = p;
}
cout << endl;
cout << p << " ate the most pcakes # " << max << endl;
return 0;
}
I'm on my phone, so I do apologize if there is formatting problems.
You say that your code falls apart at your second if-statement yet there is only one if-statement, so I am assuming it is the second line in the if-statement. However, there are two problems with this.
You aren't recording the person properly with this:
pancakes[x]=p;
This "should be":
p=x;
You need to put curly braces around the entire statement. For example:
if (i > max) {
max= i;
p=x;
}
Your loop and if statement should be as follow. See details and explanation in comments:
for (int x=0; x<9; x++) // You need to exclude 9 (do not use <=) because the index start at 0
{
cout << "Enter number " << endl;
cin >> i;
//pancakes[x] = i; <-- This line and the array is not needed. With this also you actually don't need to
// store/save what people enter. You just need to keep the max and index
if(i > max) // if i (number entered) is bigger than the current max of pancakes
{
max = i; // You update the max to the new number entered (i)
p = x + 1; // you store in p the array index + 1 (your array index start at 0 not 1)
// of the current person who eat the max number of pancakes
}
}
For the initialization:
//int pancakes[9] = {0,0,0,0,0,0,0,0,0}; <- The array is not needed. See my comment in above code
int max = 0; // More clean and readable
A few things:
1) Your iteration is wrong. It should be:
for (int x = 0; x < 9; ++x)
If you use x <= 9 you will actually do 10 iterations of the loop and the last iteration will run off the end of the pancakes array and corrupt memory.
2) When you find a new max, also set p equal to x to remember who had the most pancakes.
3) You initialize max to be pancakes[0]. While that will actually give you the right answer in this instance, you should instead explicitly initialize max = -1 to indicate an invalid maximum when you start. You also should initialize p = -1 to indicate an invalid eater when you start. These initializations would allow you to distinguish and handle the case when there is no input too.
4) Optimization: you really don't need an array to remember the # of pancakes each person ate if this is all you are doing. You can just loop as many times as you want reading input and compare against max.