So I'm reading C++ Primer (5th edition) and this is the example code they give to explain the while statement:
#include <iostream>
int main()
{
int sum = 0, val = 1;
// keep executing the while as long as val is less than or equal to 10
while (val <=10) {
sum += val; // assigns sum + val to sum
++val; // add 1 to val
}
std::cout << "Sum of 1 to 10 inclusive is " << sum << std::endl;
return 0;
}
And this is the program in the Command Line prompt:
I just can't understand where the 55 came from..
Isn't it supposed to be:
sum = 0
var = 1
sum = 0 + 1
var = 1 + 1
-snip-
sum = 6
var = 4
So shouldn't it print 6?
I'm really confused.
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55
What it does is:
initializes val to 1
increments val till it reaches 10 in each iteration
this val is added to sum in each iteration
after 10 iterations, this sums up to 55.
Still not clear, use a debugger and check each step.
Related
This question already has answers here:
Understanding recursion [closed]
(20 answers)
Closed 11 months ago.
int sum(int k) {
if (k > 0) {
return k + sum(k - 1);
} else {
return 0;
}
}
int main() {
int result = sum(10);
cout << result;
return 0;
}
It's a C++ code
I don't understand, when you return in the 3rd like (return k + sum(k-1);
aren't we returning
10 + 9 together?
Not like 10+9+8+7+6+5+4+3+2+1=55 (Original Output)
shouldn't this be the output?
by this I mean like the return is something like 10+9 then again 9+8 again 8+7
So the output might be like
10+9+9+8+8+7+7+6+6+5+5+4+4+3+3+2+2+1+1+0+0? (ac to me the sum would be like this)
The output would be one hundred?
I know I am wrong but please clear this for me.
This summation function is using recursion (basically when a function contains a callback of itself inside).
When you call sum(10), the value you will get is 10 + sum(9), not just 10 + 9. Then sum(9) == 9 + sum(8) and so on until sum(10) == 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + sum(0) which will break the recursion and will just return a constant 0, and the function will finally return 55.
There won't be any repeating results as sum(k - 1) does not contain k in its sum.
The Sum function is equal to f(n) = n + f(n - 1) on math statements.
f(10) = 10 + f(9) = 10 + 9 + f(8) = ... = 10 + 9 + 8 + ... + f(1) = 10 + 9 + 8 + ... + 1 + f(0)
And,
f(0) = 0
So,
f(10) = 10 + 9 + 8 + ... + 1 + 0
You can see what actually happens by using a debugger. Or by adding console output to the code:
#include <iostream>
int sum(int k) {
if (k > 0) {
auto sk = sum(k-1);
std::cout << "sum(" << k << ") return " << k << " + " << sk << "\n";
return k + sk;
} else {
return 0;
}
}
int main() {
int result = sum(10);
std::cout << result;
}
Output is:
sum(1) return 1 + 0
sum(2) return 2 + 1
sum(3) return 3 + 3
sum(4) return 4 + 6
sum(5) return 5 + 10
sum(6) return 6 + 15
sum(7) return 7 + 21
sum(8) return 8 + 28
sum(9) return 9 + 36
sum(10) return 10 + 45
55
sum(10) returns 10 + sum(9). It does not return 10 + 9. And sum(9) returns 9 + sum(8) ... and so on... and sum(1) returns 1 + sum(0) which is 1.
sum(k-1) call the function just like sum(10) calls it in main. Recursion often causes confusion, but it is not much different from calling an ordinary function (that might call others functions, including itself).
It works exactly like these non-recursive functions, because recursive functions work exactly like non-recursive functions.
int sum_0() {return 0;}
int sum_1() {return 1 + sum_0();}
int sum_2() {return 2 + sum_1();}
int sum_3() {return 3 + sum_2();}
int sum_4() {return 4 + sum_3();}
int sum_5() {return 5 + sum_4();}
int sum_6() {return 6 + sum_5();}
int sum_7() {return 7 + sum_6();}
int sum_8() {return 8 + sum_7();}
int sum_9() {return 9 + sum_8();}
int sum_10() {return 10 + sum_9();}
int main() { cout << sum_10(); }
So i've been attempting this problem for the last few days and have no luck. I am tasked to find square pairs from 1 to x.
Num1 + Num2 = a perfect square (i.e. 2 + 2 = 4. 16 + 20 = 36)
Num2 - Num1 = a perfect square. (i.e. 2 - 2 = 0. 20 - 16 = 4)
I've been getting closer to a result, but for the life of me can not figure out whats going wrong in my loops.
for example: this is my latest approach:
Function to test if a number is a perfect square:
bool isSquare(int num){
if(num < 0)
return false;
int root = round(sqrt(num));
return num == root * root;
}
main:
int num1 = 1; num2 = 2;
int tempP, tempM;
for(int i = 1; i <= number; i++){
for(int j = 1; j <= num1; j++){
tempP = num1 + num2;
tempM = num2 - num1;
if(isSquare(tempP) && isSquare(tempM)){
cout << num1 << "\t" << num2 << "\t" << tempP << "\t" << tempM << endl;
}
num2++;
}
num1++;
}
for some reason my output (regardless of how big 'int number' is) is limited to one row. My other tests(such as having the second loop go until j <= number) end with my num1s repeating themselves, num2s going past number, and printing every number until it stops.
I have no idea where to go next, any pointers would be helpful.
Thank you all
EDIT:
expected output of 12:
N P N + P P – N
2 2 4 0
4 5 9 1
6 10 16 4
8 8 16 0
8 17 25 9
10 26 36 16
12 13 25 1
12 37 49 25
Actual output of 12:
N P N + P P – N
2 2 4 0
num2 is always increasing. You need to reset num2 to an appropriate value at the start of your i loop (before starting the j loop).
The problem is your double loop is incrementing incorrectly. And 1201ProgramAlarm beat me to the punch... num2 never gets reset to 2, so it just keeps growing.
Instead try using the variable from your second loop instead of num2 and see what happens.
Also, comment out or remove num2++;
To avoid brute-force exhaustive searching and checking of squareness, you could use reverse math logic to generate only appropriate pairs. Let
a=num2
b=num1
a >= b > 0
It is known that
a + b = k^2
a - b = m^2
Subtract these equations:
2 * b = k^2 - m^2 = (k-m) * (k+m)
We can see that k and m must have the same oddity - both even or both odd (and b is always even).
So we can enumerate k = 2, 3, 4..., for every k get possible m = k-2, k-4, k-6... and get all (a,b) pairs.
b = (k^2 - m^2) / 2
a = k^2 - b
k m b a
2 0 2 2
3 1 4 5
4 0 8 8
4 2 6 10
5 1 12 13
5 3 8 17
6 0 18 18
6 2 16 20
6 4 10 26
...
One more approach: enumerate even b's, for every b generate all factorizations of b/2 into 2 multipliers p and q (b/2 = p * q, p >= q) and calculate possible variants of k=p+q and a = k^2-b
Example for b=24:
b/2 = 12
p q k a
12 1 13 145
6 2 8 40
4 3 7 25
Your code looks convoluted since i and j increases along with num1 and num2 anyways, so why not combine them?
for (int N = 1; N <= number; N++)
{
for (int P = 0; P <= number; P++)
{
if (ceilf(sqrtf(N+P)) == sqrtf(N+P) && ceilf(sqrtf(P-N)) == sqrtf(P-N))
{
cout << left << setw(10) << N << setw(10) << P << setw(10) << P + N << setw(10) << P - N << endl;
}
}
}
include the cmath library
Trying to debug an EXEC_BAD_ACCESS error on a C++ program. The program is taking as input numbers which are converted to strings. I then want to return the ordering of the ints that would generate the largest possible number.
The main is
int main() {
// Number of ints to input
int n;
std::cin >> n;
vector<string> a(n);
// Input numbers as strings
for (size_t i = 0; i < a.size(); i++) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end(), is_greater_than_or_equal);
std::cout << largest_number(a);
std::cout << std::endl;
return 0;
}
Using lldb, it looks like the error is coming from the sort / is_greater_than_or_equal functions.
is_greater_than_or_equal is
bool is_greater_than_or_equal(string n1, string n2) {
int l1 = n1.length();
int l2 = n2.length();
int min = (l1 < l2) ? l1 : l2;
for (int i = 0; i < min; i++) {
// First digit is strictly larger
if (n1[i] > n2[i]) {
return true;
// First digit is strictly lower
} else if (n1[i] < n2[i]) {
return false;
// First digits are the same
} else {
// If first is single digit
if (l1 == 1) {
return true;
// If the second is single digit
} else if (l2 == 1) {
return false;
// If they're both multiple digits
} else {
int j = i + 1;
// Keep checking until hitting min
while (j < min) {
if (n1[j] > n2[j]) {
return true;
} else if (n1[j] < n2[j]) {
return false;
} else {
j++;
}
}
// If min was hit and nothing was returned
// choose integer with lowest length
if (l1 > l2) {
return false;
}
return true;
}
}
}
return false;
}
After checking with lldb, it seems like the sort function keeps going way past a.end() - I believe this is what's causing the error but I'm not sure why this would happen. The reason for this is that examining the calls to is_greater_than_or_equal reveal calls like
(lldb) fr v
(std::__1::string) n1 = "9"
(std::__1::string) n2 = "2"
(int) l1 = 0
(int) l2 = 0
(int) min = 0
at first but then, after a while, they become
(lldb) fr v
(std::__1::string) n1 = ""
(std::__1::string) n2 = ""
(int) l1 = 0
(int) l2 = 0
(int) min = 0
which clearly should not happen (btw, I'm setting the breakpoint before l1 and l2 are assigned which is why the length is not matching above - the point is really just to see n1 and n2).
The output from lldb is
(lldb) r
Process 7405 launched: '/Users/etc' (x86_64)
100
2 8 2 3 6 4 1 1 10 6 3 3 6 1 3 8 4 6 1 10 8 4 10 4 1 3 2 3 2 6 1 5 2 9 8 5 10 8 7 9 6 4 2 6 3 8 8 9 8 2 9 10 3 10 7 5 7 1 7 5 1 4 7 6 1 10 5 4 8 4 2 7 8 1 1 7 4 1 1 9 8 6 5 9 9 3 7 6 3 10 8 10 7 2 5 1 1 9 9 5
Process 7405 stopped
* thread #1: tid = 0x2f2a6, 0x00007fff97c82051 libsystem_platform.dylib`_platform_memmove$VARIANT$Ivybridge + 49, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00007fff97c82051 libsystem_platform.dylib`_platform_memmove$VARIANT$Ivybridge + 49
libsystem_platform.dylib`_platform_memmove$VARIANT$Ivybridge:
-> 0x7fff97c82051 <+49>: rep
0x7fff97c82052 <+50>: movsb (%rsi), %es:(%rdi)
0x7fff97c82053 <+51>: popq %rbp
0x7fff97c82054 <+52>: retq
I'm not really sure how to interpret this output nor am I entirely aware of the inner workings of the sort.
#include <iostream>
using namespace std;
int main()
{
int a[4] = {7,9,3,4};
for (int i = 1; i < 4; i++) {
a[0]+=a[i]+1;
}
cout << a[0];
}
I ran this code through the compiler and the answer turns out to be 26. Now i'm trying to understand how to arrive at that answer.
I'm pretty sure that the for loop initialization starts with the counter variable 1, the condition is i < 4 which is initially true and the loop will continue to increment i with an output of 1,2,3 until i = 4 and the condition is false.
Now what I don't understand is what happens next in the process. Am I taking index a[0] which is 7 and adding that to "a[i]+1"? If so what is the value of "a[i]+1"?
It's doing 3 steps:
a[0] += a[1] + 1
a[0] += a[2] + 1
a[0] += a[3] + 1
i.e.:
a[0] = 7 + 9 + 1 = 17
a[0] = 17 + 3 + 1 = 21
a[0] = 21 + 4 + 1 = 26
It's giving the sum of the array plus 3, because there are three steps in the computation.
In this loop
for (int i = 1; i < 4; i++) {
a[0]+=a[i]+1;
}
a[0] accumulates values of (including itslef) a[1] + 1, a[2] + 1, and a[3] + 1 respectively according to the changes of the loop variable i in each iteration of the loop.
As the initial value of a[0] is 7
int a[4] = {7,9,3,4};
then you will have
7 + ( 9 + 1 ) = 17
17 + ( 3 + 1 ) = 21
21 + ( 4 + 1 ) = 26
I'm doing the problems on Project Euler in C++, but I'm not getting the right answers to the first one.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int b;
int c;
for (int a = 0; a <= 1000;)
{
a = a + 3;
b = a + b;
}
cout << b << "\n";
for (int a = 0; a <=1000;)
{
a = a + 5;
c = a + c;
}
cout << c << "\n";
b = b + c;
cout << b << "\n";
return 0;
}
My output is:
167835
101505
269340
Where's the error in my logic?
You are adding all values that are both multiples of 3 and 5 (i.e. multiples of 15) twice. Additionally, you will also include 1002 and 1005, which probably isn't intended.
You're double counting numbers that are multiples of 3 and 5 (i.e. multiples of 15).
Consider, Find the sum of all multiples of 3 up to 20?
Ans : =>
3, 6, 9, 12, 15 this are multiples of 3 up to 20
Sum of all multiple of 3 up to 20 is => [3 + 6 +9 + 12 + 15]
(3 + 6 +9 + 12 + 15) you can rewrite in following way
3 (1+ 2+3 +4+5 ) = > 3 (15) => 45
sum of sequence can be calculated using following formula
K(K+1)/2 = > here K is 5 => 5 (5+1)/2 = >15
In general, We can say that multiple of any number (N) within given range R
K = R/N;
N* (K (K+1))/2
In our case R =20 and N =3
int sumDivisibeBy(int R, int N)
{
int K = R / N;
int SEQSUM = ((K*(K + 1)) / 2));
return (N*SEQSUM)
}
In your case you need to call this function thrice =>
sumDivisibeBy(1000,3) + sumDivisibeBy(1000,5)-sumDivisibeBy(1000,15)
Along with double counting multiples of 15, your increments are in the wrong order. If you increment a first, you will have values above 1000. Also I'm not sure about c++ initializing ints, but maybe set them equal to 0, at least for readers.
wouldn't bother incrementing by 3 and by 5, you can increment by 1 and check whether numbers are divisible by 3 or by 5. Computers are designed for number crunching.
int sum = 0;
for (int i = 0; i < 1000; i++)
{
if (i%3 == 0 ||
i%5 == 0)
{
sum += i;
}
}
cout << "SUM:" << sum << endl;
While others have posted exactly where you've erred, you should be trying to figure out how you got the wrong answer as well.
In your case, you could have written all the values you determined to be multiples of 3 and multiples of 5; then you could have analyzed the 333 multiples of 3 you should've seen and the 199 multiples of 5 you should've seen.
I don't want to give away the keys to finding the actual solution (despite the fact that others have already) but part of the problem solving at PE is debugging.