I am attempting to learn C++ by tackling the Project Euler challanges. I am currently stuck on the first project where my while loop does not work. I have looked at it for over half an hour now but just can't see any issues with it, even though it's incredibly basic.
#include <iostream>
int main() {
int sum_3 = 0;
int i = 1;
while ( sum_3 < 1000 ) {
sum_3 = sum_3 + (i * 3);
i++;
return sum_3, i;
}
std::cout << sum_3 << std::endl;
return 0;
}
I am trying to sum every number which is a multiple of 3 but smaller than 1000. I have re-written the program, entered print statements to try and troubleshoot it, but I'm just going around in circles now.
The return keyword leaves the current function, not just the current scope.
return sum_3, i;
doesn't do what you think it does, either. You can only return a single object. The reason the line compiles is that C++ has a , operator which evaluates the expression on the left, discards the result, and then evaluates the expression on the right. So
return sum_3, i;
simply returns i.
Because the loop is in main, returning also ends the program.
Your code should probably just look like this:
while ( sum_3 < 1000 ) {
sum_3 = sum_3 + (i * 3);
i++;
}
You should not return unless you want to get off your function, in this case is the main function.
#include <iostream>
int main() {
int sum_3 = 0;
int i = 1;
while ( sum_3 < 1000 ) {// I'd use a 'for' here, if I were you
sum_3 += (i * 3); //is the same for sum_3 = sum_3 + (i * 3);
i++;
}
std::cout << sum_3 << std::endl;
return 0;
}
What needs to be smaller than 1000? The total or the individual multiples of 3?
If what you want is the total to not exceed 1000, then just remove the line "return sum_3, i" and you're good to go.
If what you wanted was to sum all multiples of 3 that are also smaller than 1000 (but the total can exceed 1000) then you need to also change the while condition to "(i*3)<1000" instead of "sum_3<1000".
Related
I'm supposed to write a small code that generates a random number between 2 and 100 and then checks if its a perfect number. I don't get any bugs from the compiler but the output doesn't show my cout lines like " x is a perfect number". Can someone help me with finding the reason?
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
bool PerfectCheck(int x) {
int t; // divisor
int sum; // sum of divisors
for (t = 0; t <= x; t++ ) {
if (x%t == 0) {
sum = sum + t;
}
}
if (sum == x)
return true;
else
return false;
}
int main() {
srand(time(NULL));
int x = rand()%(100-2+1)+2;
if (PerfectCheck(x) == true )
cout << x << "is a perfect number.";
else
cout << x << "is not a perfect number.";
return 0;
}
There are three problems in your PerfectCheck function. First, you don't initialize the sum variable, so it can start off with any value whatsoever; you should set it to zero explicitly in the declaration.
Second, your for loop starts with t as zero, and you check x % t. The modulo operator implicitly involves a division, so using a left-hand value of zero has the same issue as trying to divide by zero, which will cause a crash.
Third, when checking for a perfect number, don't use that number itself in the sum; so, stop your loop with t < x instead of t <= x.
Also, as mentioned in the comments, you can simplify the return statement. The code below works, in the tests I have performed:
bool PerfectCheck(int x)
{
int sum = 0; // sum of divisors - MUST BE INITIALIZED (to zero)
for (int t = 1; t < x; t++) { // DO NOT INCLUDE X ITSELF!!
if (x % t == 0) {
sum += t;
}
}
return (sum == x); // This will already give a "true" or "false" bool value.
}
You could actually make the code a tiny bit more 'efficient', by initializing sum to 1 and then starting the loop from t = 2 (all numbers divide by 1, after all).
Feel free to ask for further clarification and/or explanation.
if (x%t == 0) calculates the remainder after dividing x by t and compares the result with 0. That statement is correct, but look at the previous code for (t = 0; t <= x; t++ ) {. The first value of t is 0, so you have a division by zero. More than likely that is crashing your program which is why you see no output. Change for (t = 0; t <= x; t++ ) { to for (t = 1; t <= x; t++ ) {.
Also I believe the definition of a perfect number does not include division by the number itself. So the for loop should actually be for (t = 1; t < x; t++ ) {.
Finally you are using the sum variable to add up the divisors but you do not give it an initial value. Your code should say int sum = 0;.
Three errors in a ten line program (plus various style issues). Imagine how many errors here might be in a 5000 line program. Programming is tricky, you have to be very focused and get your code exactly right, nearly right is not good enough.
The code that I did was for solving the following problem. However, the logic of the code is wrong and I as a good newbie cannot figure what is wrong.
After I compile the result of 'sum' is always 0, if I change the initialization of 'sum' for a whatever number, that whatever number is what appear as answer of 'sum'.
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
long sum = 0;
for( long i; i < 1000; ++i )
{
if (( i % 3 == 0 ) || ( i % 5 == 0 ))
{
sum = sum + i;
}
}
cout << "The sum is: " << sum << endl;
return 0;
}
You need to initialize i in your loop:
for (long i = 0; i < 1000; ++i )
As it is, i is probably some random number greater than 0 at the top of the loop, and the result is that the loop is never executed.
You need to initialize i to zero otherwise i's value will be whatever happens to be in memory. In this case it's > 1000.
for (long i = 0; i < 1000; ++i)
Also, a nice trick I learned. Use ii as your index variable. It's much easier to find ii than just i in your code.
You forgot to set i=O in your loop so the loop won't iterate.
All answers above are correct - you need to set your i to 0. What you might be interested in is that accessing uninitialized variable is an "undefined behaviour" (UB) and modern compilers are actually pretty good in finding the UBs and using them to optimize the code. For example, GCC 5.2 with -O2 (optimizations enabled) will generate same assembly for your code and for one without the loop at all regardless of what might happen to be in the memory at the address of i.
Try putting this code to (which is your code with additional #if for convenience) this online disassembler
#include <iostream>
using std::cout;
using std::endl;
int main()
{
long sum = 0;
#if 1
for (long i; i < 1000; ++i)
{
if ((i % 3 == 0) || (i % 5 == 0))
{
sum = sum + i;
}
}
#endif
cout << "The sum is: " << sum << endl;
return 0;
}
add the -O2 flag to compiler options on top right and try changing #if 1 to #if 0 and observe that the disassembly is the same meaning that the compiler cut out the loop completely.
The program runs but it also spews out some other stuff and I am not too sure why. The very first output is correct but from there I am not sure what happens. Here is my code:
#include <iostream>
using namespace std;
const int MAX = 10;
int sum(int arrayNum[], int n)
{
int total = 0;
if (n <= 0)
return 0;
else
for(int i = 0; i < MAX; i ++)
{
if(arrayNum[i] % 2 != 0)
total += arrayNum[i];
}
cout << "Sum of odd integers in the array: " << total << endl;
return arrayNum[0] + sum(arrayNum+1,n-1);
}
int main()
{
int x[MAX] = {13,14,8,7,45,89,22,18,6,10};
sum(x,MAX);
system("pause");
return 0;
}
The term recursion means (in the simplest variation) solving a problem by reducing it to a simpler version of the same problem until becomes trivial. In your example...
To compute the num of the odd values in an array of n elements we have these cases:
the array is empty: the result is trivially 0
the first element is even: the result will be the sum of odd elements of the rest of the array
the first element is odd: the result will be this element added to the sum of odd elements of the rest of the array
In this problem the trivial case is computing the result for an empty array and the simpler version of the problem is working on a smaller array. It is important to understand that the simpler version must be "closer" to a trivial case for recursion to work.
Once the algorithm is clear translation to code is simple:
// Returns the sums of all odd numbers in
// the sequence of n elements pointed by p
int oddSum(int *p, int n) {
if (n == 0) {
// case 1
return 0;
} else if (p[0] % 2 == 0) {
// case 2
return oddSum(p + 1, n - 1);
} else {
// case 3
return p[0] + oddSum(p + 1, n - 1);
}
}
Recursion is a powerful tool to know and you should try to understand this example until it's 100% clear how it works. Try starting rewriting it from scratch (I'm not saying you should memorize it, just try rewriting it once you read and you think you understood the solution) and then try to solve small variations of this problem.
No amount of reading can compensate for writing code.
You are passing updated n to recursive function as argument but not using it inside.
change MAX to n in this statement
for(int i = 0; i < n; i ++)
so this doesnt really answer your question but it should help.
So, your code is not really recursive. If we run through your function
int total = 0; //Start a tally, good.
if (n <= 0)
return 0; //Check that we are not violating the array, good.
else
for(int i = 0; i < MAX; i ++)
{
if(arrayNum[i] % 2 != 0) //THIS PART IS WIERD
total += arrayNum[i];
}
And the reason it is wierd is because you are solving the problem right there. That for loop will run through the list and add all the odd numbers up anyway.
What you are doing by recursing could be to do this:
What is the sum of odd numbers in:
13,14,8,7,45,89,22,18,6,10
+
14,8,7,45,89,22,18,6
+
8,7,45,89,22,18
+
7,45,89,22 ... etc
And if so then you only need to change:
for(int i = 0; i < MAX; i ++)
to
for(int i = 0; i < n; i ++)
But otherwise you really need to rethink your approach to this problem.
It's not recursion if you use a loop.
It's also generally a good idea to separate computation and output.
int sum(int arrayNum[], int n)
{
if (n <= 0) // Base case: the sum of an empty array is 0.
return 0;
// Recursive case: If the first number is odd, add it to the sum of the rest of the array.
// Otherwise just return the sum of the rest of the array.
if(arrayNum[0] % 2 != 0)
return arrayNum[0] + sum(arrayNum + 1, n - 1);
else
return sum(arrayNum + 1, n - 1);
}
int main()
{
int x[MAX] = {13,14,8,7,45,89,22,18,6,10};
cout << sum(x,MAX);
}
So I'm trying to figure out how to do this:
Write a recursive function that will sum all of the char's within a C String.
I'm a little rusty in doing this normally, but I finally got it to work with a normal for loop:
int countstr(string s)
{
int sum = 0;
if(s.length() == 0)
{
exit(0);
}
for (unsigned int i = 0; i < s.size(); i++)
{
sum += s[i];
}
return sum;
}
I can then go inside main and do this:
int main ()
{
cout << "This word adds up to " << countstr("HELLO") << " in ASCII " << endl;
}
and everything works as it should, counting and adding up the characters in the string via their ASCII numbers.
The problem I'm having is trying to figure out how this is typed up so it works recursively. I know I need to forgo the for loop in lieu of calling up the function itself, but I don't know what to use instead of the sum += s[i]; that I have going in my for loop. I've been looking around in the C string library, but I don't see anything that can replace the [i] that the for loop calls up. Does anyone know what I should be using to do this? I'm not looking for an answer in code, just need help in what I should be using to make this happen.
This is one of many ways to do it.
int reccountstr(string s, int i){
if(s.size() == i)
return (0 + s[i]);
else
return reccountstr(s, i + 1) + s[i];
}
And then in main you just call it with a zero initial argument.
cout << "This word adds up to " << reccountstr("HELLO", 0) << " in ASCII " << endl;
Skeleton could be like this:
int countlen(const char * str)
{
if (condition)
return 0;
else
return *str + countlen(str + 1);
}
The rest is up to you :)
int countString(char sample[], int i)
{
if(sample[i] == 0)
return 0;
else
return(1 + countString(sample, i+1));
}
This could be one solution, where if the current character read is not null (0, or '\0') it will return 1 + countString(sample, i + 1) where i is the current character index to be read.
Once it reaches null it returns 0. So for a character length of three, it will do 1 + 1 + 1 + 0. You can call the function with printf("%d\n", countString(yourStringName, 0)).
So your base case here is character[index] == empty
Your inductive case is 1 + function(stringName, index + 1), roughly speaking.
Also, this is a little outside the scope of your question, but you can also make this more efficient by avoiding constantly building up the stack. A way to do this is to create another variable inside the function that continuously accumulates the total count. For more info on this see this link on tail recursion:
http://c2.com/cgi/wiki?TailRecursion
More memory conservative version:
int countString(char sample[], int i, int total)
{
if(sample[i] == 0)
return total;
else
return countString(sample, i+1, ++total);
}
You can call this with printf("%d\n", countString(sample, 0, 0));
I'm doing the first project euler problem and I just did this
#include <iostream>
using namespace std;
int main(){
int threes =0;
int fives = 0;
int both = 0;
for (int i = 0; i < 10; i++){
if(i%3==0){
threes += i;
}
if(i%5==0){
fives += i;
}
if ( i % 5 == 0 && i % 3 == 0){
both += i;
}
}
cout << "threes = " << threes << endl;
cout << "fives = " << fives << endl;
cout << "both = " << both << endl;
cout << " threes + fives - both = " << endl;
int result = (threes + fives) - both;
cout << result<< endl;
return 0;
}
My professor recently corrected me for doing this in a different problem saying something about else statements,
but I don't understand WHY i have to add else in front of the next if. for what its worth I have another version with else if(i%5){ fives += .... }
and they both work and get me the right answer.
My question is whats inherently wrong with this way of thinking, is it stylistic or am I not thinking logically about something?
If it works, why use switch statements ever?
The only thing that I see wrong with your implementation is that in the case where the number is both a multiple of 3 and a multiple of 5 not only is the both variable incremented but the fives and threes variables are also incremented. Based on what the professor described I believe he wants you to use an else-if so that the both variable is the only one that is incremented when you pass in a number that is both a multiple of 3 and a multiple of 5.
The reason you get the correct answer both ways is because you are only going to 10 in the for loop, if you increase it to i <= 15 you will get fives and threes being 1 higher than I think he intended.
For example:
for( int i = 0; i < 10; i++ )
{
if( ( ( i % 3 ) == 0 ) && ( ( i % 5 ) == 0 ) )
{
both++;
}
else if( ( i % 3 ) == 0 )
{
threes++;
}
else if( ( i % 5 ) == 0 )
{
fives++;
}
}
The else branch in an if-else statement is only executed if the if branch is false. If you just have two if statements in a row, they'll both be executed, which can be a waste. In the below code, the else prevents the second computation from running if the first is satisfied.
if (expensive_computation1()) {
...
}
else if (expensive_computation2()) {
...
}
Additionally, it's clearer to humans reading the code whether both if statements should be allowed to run or whether only one should.
In this case, maybe you really want this:
if (i % 5 == 0 && i % 3 == 0) {
both += i;
} else if (i % 3 == 0) {
threes += i;
} else if (i % 5 == 0) {
fives += i;
}
(why you do += i instead of ++ I don't know but you didn't explain, so I just copied it)
In your code, threes and fives were incremented even if it would also increase both, which depending on your problem may not be what you want. If you do the if/else way I've just presented, only one of the three variables is increased.
Why use if-else instead of multiple if's?
if-else & if would achieve the same results but if-else achieves them in a performance enhanced way. with multiple if's every if condition will have to be checked. With if-else only one conditional check will have to be performed and the rest of the conditions just don't need to be checked at all.
This would not affect a small program like the one you have but it will sure have some impact in potentially expensive function being called repeatedly over and over again.
If it works, why use switch statements ever?
With nested if-else conditions the code is hard to read and understand. The switch-case construct helps to represent the conditions in a much easier to read & understand format.
To me it looks like stylistics. You can use some autoreformating tool that follows certain established stylistic look (K&R, ANSI, GNU, etc.)
For example astyle is such tool, http://astyle.sourceforge.net/ - just reformat your code with it, and you might have a happy professor.