The program I wrote below seems to be doing its job, but it produces the wrong answer. As described in the comments, I need to multiply 5 consecutive digits of the 1000-digit string and then find the largest product throughout the entire string.
/*
OBJECTIVE: Multiply five consecutive numbers and then compare products to find largest product
PROVE: 40824
*/
#include <iostream>
using namespace std;
int main()
{
// string length is 1000 characters
string str = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int store = 0; // what I need to compare total to later
int total = 1; // total must be '1' for multiplication or result is always '0'
for(int i = 0;i<=999;) // i = 0 because that's the starting point for place of first number in string (str[0]); because the length is 1 short, 999 is the limit
{
total = 1; // what will be multiplied by inputs from str[]
int incr = i + 4; // places for the next 5 now that 0-4 are out of the way would be 5,6,7,8,9
// A general note: pattern this generates is that the end digit of an even break in groupings will always either be 4 or 9
// e.g. breaking the loop at position 44, 199, 234 will multiply 5 places properly without error
if(i == 0) // when starting out i = 0
{
for(;i<=4;i++) // i = str[0] which is then incrmemented to str[4] which is fifth number
{
cout << "i: " << i << '\t' << "str[" << i << "]: " << str[i] << '\t';
total*=(str[i] - '0'); // takes str[1],str[2],...str[4] and multiplies them together using total as valueholder.
// " - '0' " is because string numbers return ASCII codes
cout << "Total Product: " << total << '\t';
cout << "Store: " << store << '\t' << endl;
};
store = total > store ? total:store; // if total is greater than store, then store = total; simple enough
cout << endl; // line-break after first set of five
};
if(i>=5) // i is no longer 0
{
for(;i<=incr;i++) // i must be added by 5 now because 0,1,2,3,4 are first five and 5,6,7,8,9 are next
{
cout << "i: " << i << '\t' << "str[" << i << "]: " << str[i] << '\t';
total*=(str[i] - '0'); // takes str[1],str[2],...str[4] and multiplies them together using total as valueholder.
// " - '0' " is because string numbers return ASCII codes
cout << "Total Product: " << total << '\t';
cout << "Store: " << store << '\t' << endl;
};
store = total > store ? total:store; // if total is greater than store, then store = total; simple enough
cout << endl; // line-break after each set of five
};
};
cout << endl << endl << store; // final output; what should be answer
return 0;
}
The program shows that it is indeed multiplying five consecutive digits together and successfully bumping the store value when necessary, alas I still get a wrong answer of 31752 which should be 40824 (According to the Project Euler Solutions google-group: http://code.google.com/p/projecteuler-solutions/). What have I done wrong? What must I do to fix this program? Any tips for the future to avoid the probably-stupid mistake I'm not seeing?
From a cursory glance, I believe your problem lies in the fact that you modify i in multiple locations aside from the for loop declaration. This would cause your scan through the number to skip over sequences that could have potentially been correct.\
If you reason out your code, it starts at position 0 in the string. Then you have a conditional where you increment i 4 times, so then the next time through the loop, you start attempting to find a sequence starting at position 4 in the string, rather than starting at position 1.
Fixed Code:
/*
OBJECTIVE: Multiply five consecutive numbers and then compare products to find largest product
PROVE: 40824
*/
#include <iostream>
using namespace std;
int main()
{
// string length is 1000 characters
string str = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int store = 0; // what I need to compare total to later
int total = 1; // what will be multiplied by inputs from str[]
int n = 0; // keeps track of single iterations
for(int i = 0;n<=999;n++) // i = 0 because that's the starting point for place of first number in string (str[0]); because the length is 1 shorter, 999 is the limit
{
total = 1; // must be set back to one each successful product loop
int incr = n + 4; // places for the next 5 after 0
// A general note: pattern this generates is that the end digit of an even break in groupings will always either be 4 or 9
// e.g. breaking the loop at position 44, 199, 234 will multiply 5 places properly without error
if(n == 0) // string starts at 0, must be accounted for especially
{
for(;i<=4;i++) // i = str[0] which is then incrmemented to str[4] which is fifth number
{
cout << "n: " << n << '\t' << "str[" << i << "]: " << str[i] << '\t';
total*=(str[i] - '0'); // takes str[1],str[2],...str[4] and multiplies them together using total as valueholder.
// " - '0' " is because string numbers return ASCII codes
cout << "Total Product: " << total << '\t';
cout << "Store: " << store << '\t' << endl;
};
store = total > store ? total:store; // if total is greater than store, then store = total; simple enough
};
for(;i<=incr;i++) // i must be added by 4 now because 0,1,2,3,4 are first five and 1,2,3,4,5 are next
{
cout << "n: " << n << '\t' << "str[" << i << "]: " << str[i] << '\t';
total*=(str[i] - '0'); // takes str[1],str[2],...str[4] and multiplies them together using total as valueholder.
// " - '0' " is because string numbers return ASCII codes
cout << "Total Product: " << total << '\t';
cout << "Store: " << store << '\t' << endl;
};
store = total > store ? total:store; // if total is greater than store, then store = total; simple enough
i = (n + 1); // i needs to start at a consecutive n each successful loop
};
cout << endl << endl << store;
return 0;
}
well, this problem makes me think of the Pattern Match Algorithm "KMP".
probably you should check out KMP, may gain some hint.
Related
I am new to C++.
Below is code that lets a user enter five elements into an array, then sums those values, and obtains the mean and a predicted future value.
The code works fine if the user enters five elements, but how do I handle the situation in which one or more values are missing?
I have written code further below that seems to solve this problem, by defining a missing value to be a negative number. That code also seems to work fine. But, is there a better, accepted way of handling missing values in a C++ array?
If I try to run the first code in Microsoft Visual Studio 2019, I do not even know what to enter for a missing value. If I do not enter anything, and just press the Enter key, nothing happens.
Here is the original code that works with five elements. This code is slightly modified from code written by Saldina Nurak:
#include <iostream>
using namespace std;
int nmonths = 6;
int totalmonths = 24;
int main()
{
// {100, 220, 300, 0, 200, 250}
// This line works in the command window
// float monthArray[nmonths];
// for Microsoft Visual Studio 2019
float monthArray[6];
float total = 0;
for(int i = 0; i <= (nmonths-1); i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> monthArray[i];
total += monthArray[i];
}
float average = total / nmonths;
float inTwoYears = average * totalmonths;
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: 200
Enter Amount 6: 250
total = 1070
average = 178.333
inTwoYears = 4280
Here is the modified code I wrote that seems to handle missing values, by defining them to be negative numbers:
#include <iostream>
using namespace std;
int nmonths = 6;
int totalmonths = 24;
int emptycounter = 0;
int main()
{
// This works from the command window
// float monthArray[nmonths]; // {100, 220, 300, 0, -99, 250};
// for Microsoft Visual Studio I have to use
float monthArray[6];
float total = 0;
for(int i = 0; i <= (nmonths-1); i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> monthArray[i];
if (monthArray[i] >= 0) emptycounter++;
else (emptycounter = emptycounter);
if (monthArray[i] >= 0) total += monthArray[i];
else total = total;
}
float average = total / emptycounter;
float inTwoYears = average * (totalmonths - (nmonths - emptycounter));
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
C:\Users\mark_>cd C:\Users\mark_\myCppprograms
C:\Users\mark_\myCppprograms>c++ MissingDataInArray2.cpp -o MissingDataInArray2.exe -std=gnu++11
C:\Users\mark_\myCppprograms>MissingDataInArray2
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: -99
Enter Amount 6: 250
total = 870
average = 174
inTwoYears = 4002
What is the standard approach for dealing with missing values in C++ and how does a user enter a missing value from the keyboard?
You would have to define what is supposed to be a missing value if you are trying to read as a number. You could maybe read the line and try to parse it to a int and if unable to parse then it would be your missing value?
Also, you are not using C++ arrays, you are using C arrays.
C++ has an array container but vector gives you much more flexibility.
You could do something like this:
vector<int> monthArray;
int value;
for(int i = 0; i < nmonths; i++) // See the change done in the test
{
cin >> value;
if(value > 0)
monthArray.push_back(value); // This would insert at the end and take care of resizing the container as needed.
}
monthArray.size(); // This returns how many elements you have in the container
Both your else clauses are assigning a variable to itself. You can erase both and put the 2 statements inside the same if:
if (monthArray[i] >= 0)
{
emptycounter++;
total += monthArray[i];
}
But if you use vector you won't need emptycounter. The size of the vector will contain the number of valid elements.
for(int i = 0; i < nmonths; i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> value;
if(value > 0)
{
monthArray.push_back(value);
total += value;
}
}
After all that... There is this question: Do you really need an array? You just seem to accumulate the valid values and never refer to the array after saving the elements on it.
P.S: to use vector you need to #include<vector>
What is the standard approach for dealing with missing values in C++ ?
std::optional is standard and serves the need.
How does a user enter a missing value from the keyboard?
There is no definition of operator>> for istream and std::optional<float> but you can write a function that behaves the way you want.
For example you could use std::getline to always read an entire line, then if the line is blank return an empty std::optional<float> and if not then parse the number and return a std::optional<float> that contains it.
Here is code that implements the answer from #vmp when missing observations are defined as NA (as in R and suggested by #Yksisarvinen in a comment) by using stoi. I have not yet figured out how to implement the answer from #Ben Voigt.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int nmonths = 6 ;
int totalmonths = 24 ;
int main()
{
float total = 0;
vector<int> monthArray;
string value;
for(int i = 0; i < nmonths; i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> value;
if(value != "NA")
{
monthArray.push_back(stoi(value));
total += stoi(value);
}
}
float average = total / monthArray.size() ;
float inTwoYears = average * (totalmonths - (nmonths - monthArray.size())) ;
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
// C:\Users\mark_>cd C:\Users\mark_\myCppprograms
// C:\Users\mark_\myCppprograms>c++ vector2.cpp -o vector2.exe -std=gnu++11
// C:\Users\mark_\myCppprograms>vector2
// Enter Amount 1: 100
// Enter Amount 2: 220
// Enter Amount 3: 300
// Enter Amount 4: 0
// Enter Amount 5: NA
// Enter Amount 6: 250
// total = 870
// average = 174
// inTwoYears = 4002
I am trying to solve the first problem of this collection
To find and display the value of Pi till the Nth digit (taken as user input limited by some maximum value, my guess the maximum number of decimal places the biggest ds can hold which is long double i guess?)
Below is a snippet of my attempt.
//declarations
typedef numeric_limits< long double > db;
int MAX = db::digits10;
int N = 0; //digit allowance
long double pi_val = M_PI;
string string_pi;
//user input
while(1){
cout << "Enter a value of n < or = " << MAX << endl;
cin >> N;
if(N>18){cout << "Lesser please" << endl;}
else
break;
}
//outputs
cout << "Pi till the " << N << " digit is: ";
cout << setprecision(N+1) << fixed << pi_val << endl;
string_pi = to_string((long double)pi_val * pow(10, N));
cout << string_pi << endl;
cout << "The Nth digit of pi is: " << string_pi[N] << endl;
Ps I am aware that more novel ways exist to go about the problem but since I am an extreme beginner at cpp, I'd attain a better sense of achievement by making my idea work.
Now the problem, it displays the Nth digit correctly but the output of Pi till the Nth value always gets rounded off despite the 'fixed' and 'setprecision()' so I had to display an extra digit to tally with the latter output
How can I fix this problem, if possible without changing the main logic I have used
Thank you
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 20;
int main ()
{
//Declare variables
int counter; //loop control variable
int number; //variable to store the new number
int zeros = 0; //Step 1
int odds = 0; //Step 1
int evens = 0; //Step 1
int positives = 0;
int negatives = 0;
// Display Program Intro telling what the program does.
cout << "********************************************************"
<< "\n* This is a program that counts integers you enter as *"
<< "\n* even, odd or zero and positve or negative *"
<< "\n* It classifies 20 numbers or use 99999 to exit early *"
<< "\n********************************************************"
<< endl;
// Ask for 20 integers with 99999 as early exit
cout << "\n\nPlease enter " << N << " integers, "
<< "positive, negative, or zeros."
<< "\n\t\t or enter number 99999 to exit early. \n\n"
<< endl; //Step 2
cout << "The numbers you entered are:" << endl;
// Loop that classifies the numbers entered.
for (counter = 1; counter <= N; counter++) //Step 3
{
// Enter number and mirror it backed on a tabbed line.
cin >> number; //Step 3a
cout << number << endl; //Step 3b
// Early exit condition: 99999
if(number = 99999)
break; // Exit loop before 20 numbers
// Count Postive and Negative Numbers
if(number < 0)
negatives++;
else
positives++;
// Count Evens, Odds and Zeros
//Step 3c
switch (number % 2)
{
case 0:
evens++;
if (number == 0)
zeros++;
case 1:
case -1:
odds++;
} //end switch
} //end for loop
cout << endl;
// Display the results ....
//Step 4
cout << "There are " << evens << " evens, "
<< "which includes " << zeros << " zeros."
<< endl;
cout << "The number of odd numbers is: " << odds
<< endl;
cout << "The number of positive numbers is: " << positives
<< endl;
cout << "The number of negative numbers is: " << negatives
<< endl;
// Use Holdscreen to make sure the results are visible ....
char holdscr; // This character and section is to hold screen open
cout << "\n\n\tPress a character and Enter to exit program. ";
cin >> holdscr;
return 0;
}
I am debugging this program. There were originally 6 errors in the program. I've found four of them as they were syntax errors. The compiler doesn't show any error but the program isn't working either.
The program is supposed to store 20 numbers and in the end tell you how many of them were even, odd, zero, negative, and positive. I am just a beginner in C++. I have tried every possible way to solve it from my side but I cannot get it to work. I have looked up every code and syntax on Google why it works that way but found no help. Any help here would be highly appreciated.
If you enable warnings when you compile then the compiler will helpfully point out certain mistakes in your code, and if it's in a good mood it may even suggest a solution:
<stdin>:46:23: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if(number = 99999)
~~~~~~~^~~~~~~
<stdin>:46:23: note: place parentheses around the assignment to silence this warning
if(number = 99999)
^
( )
<stdin>:46:23: note: use '==' to turn this assignment into an equality comparison
if(number = 99999)
^
Always compile with warnings enabled (e.g. gcc -Wall ...) - it will save you a lot of time and debugging effort in the long run.
Create a program that takes as input a string of digits and outputs
the sum of the even and the sum of the odd digits. This program is in
C++
NOTE: It is recommended that you use a "for" loop to iterate over the
sting of digits. HINT: Use the modulus operator to determine even or
odd digits.
A clever method of converting a "char" to an "int" is as follows link:
char a = '4';
int ia = a - '0';
The above code takes advantage of the character's position in the
ASCII table to convert it to an integer.
Below is the code I have so far:
int main() {
int sumOdd = 0; // For accumulating odd numbers, init to 0
int sumEven = 0; // For accumulating even numbers, init to 0
int digits; // Sum from 1 to this upperbound
// Prompt user for an upperbound
cout << "Please enter a string comprised ONLY of digits:" << endl;
cout << endl;
cin >> digits;
// Use a while-loop to repeatedly add 1, 2, 3,..., to the upperbound
int number = 1;
while (number <= digits) {
if (number % 2 == 0) { // Even number
sumEven += number; // Add number into sumEven
} else { // Odd number
sumOdd += number; // Add number into sumOdd
}
++number; // increment number by 1
}
// Print the results
cout << "The string of digits \"" << digits << "\""
<< " contained "
<< "characters." << endl;
cout << "The sum of the even digits is: " << sumEven << endl;
cout << "The sum of the odd digits is: " << sumOdd << endl;
return 0;
}
This is my output compared to the output I need
Input:
1234567890
Output:
Please enter a string comprised ONLY of digits:
The string of digits "1234567890" contained characters.
The sum of the even digits is: -380436870
The sum of the odd digits is: -997720815
Expected output
Please enter a string comprised ONLY of digits:
The string of digits "1234567890" contained 10 characters.
The sum of the even digits is: 20
The sum of the odd digits is: 25
Overall I'm having trouble counting the input and getting the correct formula for my even and odd numbers. Any help is appreciated thank you so much!
A simple method is to keep the number in text form:
std::string number_as_text;
cout << "Enter number: ";
cin >> number_as_text;
This allows you to check each digit for even or odd:
const size_t length = number_as_text.length();
for (size_t i = 0; i < length; ++i)
{
char digit_character = number_as_text[i];
if (isdigit(digit_character))
{
if (digit_character % 2 == 0)
{
// digit is even
}
else
{
// digit is odd
}
}
}
If you don't like isdigit(), you can replace with:
if ((digit_character >= '0') && (digit_character < '9'))
An important note is that there is a difference between the textual representation of digits and the internal, numeric, representation of digits.
Edit 1: % on char type
The char data type is an integer. The remainder operator, %, works on integer types. Thus you can use % on char types.
Note: this operation assumes that the character mapping of '0' is an even integer and the other digits are successive in values.
Read the inputs in a string field and not an integer as -
std::string digits;
Then, just run a valid loop to find out the sum of the even digits and the odd digits -
for(int i=0; i<digits.length(); i++){
int digit = digits[i]-'0';
if(digit % 2 == 0)
sumEven+=digit;
else
sumOdd+=digit;
}
Below is a running piece of code.
// Example program
#include <iostream>
#include <string>
using namespace std;
int main() {
int sumOdd = 0; // For accumulating odd numbers, init to 0
int sumEven = 0; // For accumulating even numbers, init to 0
std::string digits; // Sum from 1 to this upperbound
// Prompt user for an upperbound
cout << "Please enter a string comprised ONLY of digits:" << endl;
cout << endl;
cin >> digits;
// Use a while-loop to repeatedly add 1, 2, 3,..., to the upperbound
int number = 1;
for(int i=0; i<digits.length(); i++){
int digit = digits[i]-'0';
if(digit % 2 == 0)
sumEven+=digit;
else
sumOdd+=digit;
}
// Print the results
cout << "The string of digits \"" << digits << "\""
<< " contained "
<< "characters." << endl;
cout << "The sum of the even digits is: " << sumEven << endl;
cout << "The sum of the odd digits is: " << sumOdd << endl;
return 0;
}
You got it wrong you are supposed to do sum of 1+3+5+7+9 and sum of 2+4+6+8+0. What are you doing instead is sum of all even numbers smaller than 1234567890 and sum of odd numbers smaller than 1234567890.
Maybe consider instead of getting all numbers in string by cin >> digits read it from input by characters one by one.
Check this code it reads characters from input and spits them back.
#include<iostream>
using namespace std;
int main() {
cout << "Please enter a string comprised ONLY of digits:" << endl;
cout << endl;
char one;
while ( true ) {
cin >> one;
// here will come your part with deciding even / odd and counting instead of pritnting out.
cout << " " << one;
if ( cin.peek() == '\n' ) { break; }
}
return 0;
}
And now it's your turn to put it together.
Use std::getline to read all digits into a std::string:
std::cout << "Enter string of numbers: " << std::endl;
if (std::string numbers; std::getline(std::cin, numbers)) {
/* ... */
}
Note the use of conditional-if above from the upcoming C++1z standard.
Then, you could make use of std::pair to neatly accumulate the odds and evens like this:
std::pair odd_even{0, 0};
for (auto c : numbers) {
(c % 2 ? std::get<0>(odd_even) : std::get<1>(odd_even)) += c - '0';
}
Live example
This one logically should work
for(int i=0; i<digits.lenght; i++){
if(digits[i] % 2 == 0)
sumEven+=digits[i];
else
sumOdd+=digits[i];
}
I have the following piece of code that takes in some words, stores them into a vector, sorts them, then counts how many times each word appears and outputs it:
typedef vector<double>::size_type vec_sz;
vector<string> words;
string c;
cout << "Enter some words!" << endl << endl;
while (cin >> c) {
words.push_back(c);
}
vec_sz size = words.size();
sort(words.begin(), words.end());
string current_word = words[0];
int count = 1;
for (int i = 1; i < size; i++) {
if (words[i] == current_word) {
count++;
}
else {
cout << "The word " + current_word + " appears " << count << " times." << endl;
current_word = words[i];
count = 1;
}
}
I enter some words:
word
word
lol
hello
lol
word
hello
^Z
I then get the following output:
The word hello appears 2 times.
The word lol appears 2 times.
But it never reaches the final set of words. I changed my loop to just print out each element in the vector and it does print out all of them. But for some reason this loop does not want to reach the final set of words. What is going wrong?
The last word is being reached, here:
else {
// Previous word printed
cout << "The word " + current_word + " appears " << count << " times." << endl;
// current_word set to last word
current_word = words[i];
count = 1;
}
And then the loop exits. So, you would need a final line outside the loop to print the last word and its count.
The count message is only printed when a different word is found. When the last word is found, a different word is not encountered so a message is not printed. You need a piece of code after the for to print out the count for last word.
There are other ways to achieve this, using a std::map<std::string, unsigned int> for example:
map<string, unsigned int> word_counts;
string c;
cout << "Enter some words!" << endl << endl;
while (cin >> c) {
word_counts[c]++;
}
for (map<string, unsigned int>::iterator wci = word_counts.begin();
wci != word_counts.end();
wci++)
{
cout << "The word " << wci->first << " appears " << wci->second << "times.";
}