I don't understand why this returns a 5 when 5 is entered?
does it return a 1 each time the function can make a subtraction? and then add all those ones?
#include <iostream>
using namespace std;
int Fibonacci(int);
int Fibonacci(int x)
{
if (x == 0) return 0; // Stopping conditions
if (x == 1) return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}
int main() {
int num;
cin >> num;
cout << Fibonacci(num) << endl;
return 0;
}
For clarity, using a function
auto F( int x )
-> int
{ return (x <= 1? x : F(x-2)+F(x-1)); }
F(5)
→ F(3) + F(4)
→ (F(1) + F(2)) + F(4)
→ (1 + F(2)) + F(4)
→ (1 + (F(0) + F(1))) + F(4)
→ (1 + (0 + F(1))) + F(4)
→ (1 + (0 + 1)) + F(4)
→ (1 + 1) + F(4)
→ 2 + F(4)
→ 2 + (F(2) + F(3))
and so on…
0,1,1,2,3,5 are what it calculates for getting to the value for 5. When asked for any element but the first two (here indexed as a sub 0 and a sub 1) it adds the preceding two elements (those subtractions are to the indices of the sequence, not the value). A sub zero is set to 0 and a sub one to 1.
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(); }
This is my code. 1<=i<=j<=n j-i<=a 1<=n<=1000000 0<=a<=1000000
#include <iostream>
using namespace std;
int main(){
int n, a, r = 0;
cin>>n>>a;
for(int i = 1; i <= n; i++){
int j = i;
for(j; j <= n; j++){
if(j-i<=a){
r++;
}
}
}
cout<<r;
}
Instead of loops, I changed it to a simple check of variables, which greatly accelerated the code. there is no need to calculate thousands of options.
My final, optimized code is:
#include <iostream>
using namespace std;
int main(){
unsigned long long n, a, r = 0;
cin>>n>>a;
if(a==0){
r = n;
}
if(n<=a){
r = (n*(n+1))/2;
}
if(n>a){
r += (n-a)*(a+1) + (a*(a+1))/2;
}
cout<<r;
}
After accounting for both positive numbers, negative numbers, and zeros, your double-nested for-loop can be simplified into this:
if (n < 1)
{
r = 0;
}
else if (a == 0)
{
r = n;
}
else if (a < 0)
{
r = 0;
}
else if (n <= a)
{
r = (n * (n + 1)) / 2;
}
else
{
r = (n-a)*(a + 1) + (a * (a + 1)) / 2;
}
Recall that summing a sequence of digits from 1..N is:
N*(N+1)
-------
2
If n <= a (positive numbers), r is incremented n times in the inner loop on the first iteration of the outer loop. Then n-1 times, then n-2 times... all the way down to 1.
For cases where n > a, then there are n-a summations of a+1 followed by a decrementing summation from a down to 1
This strikes me as something to speed up by doing a bit of math, not by massaging the code.
Basically, we can think of the loops as defining a square matrix of the values of i and j. So let's assume n = 9, and a = 3. I'll draw in a + for each place we increment r, a blank for the values we don't generate, and a 0 for the places we generate values, but don't increment r.
i\j 1 2 3 4 5 6 7 8 9
1 + + + + 0 0 0 0 0
2 + + + + 0 0 0 0
3 + + + + 0 0 0
4 + + + + 0 0
5 + + + + 0
6 + + + +
7 + + +
8 + +
9 +
So, ignoring the last a rows (i.e., for the first n-a rows), in each row we have a band a + 1 elements wide where we do an increment. Then at the end, we have a triangle, where we're basically summing a + a-1 + a-2 ... 0.
So, the first piece is (a+1) * (n-a) and the second piece is a * (a+1) / 2. Add those together, and we get the final answer.
Seems like
for(j; j <= n; j++){
if(j-i<=a){
r++;
}
}
could be replaced by
r += f(i,n,a);
Where f() is some simple expression involving those 3 values, probably including the equivalent of min(..,..)
If you want to speed up your code, instead of just tuning your algorithm, you can also try to use some parallel api.
Parallel computing api such as OpenMP enables you take advantage of your cpu resources.
If you uses OpenMP, you can try to use it to parallel your loop.
I am trying to understand what is happening in my recursion step return x + times(x, y-1).
Specifically times(x, y-1) Since there is no equation in the function what is happening in the recursion? I don't see how the values are added.
#include <iostream>
using namespace std;
int times(int x, int y)
{
if (x == 0 || y == 0)
return 0;
else if (y == 1)
return x;
else
return x + times(x, y - 1);
}
int main()
{
int x, y;
cout << "Enter two numbers to be multiplied seperated by a space: ";
cin >> x >> y;
cout << "The product is " << times(x, y) << endl;
return 0;
}
The best way to understand recursion is to write all the stack trace on paper.
Let's take an example of times(3, 2):
Call 1: times(3, 2) -> returns 6
Call 2: 3 + times(3, 1) -> returns (3 + 3), that is 6
Call 3: times(3, 1) -> returns 3
So, the final answer is 6.
x + times(x, y-1): It's a way of representing multiplication using addition. For example:
1) 3 * 2 = (3 + 3)
2) 4 * 3 = (4 + 4 + 4 + 4)
#dxiv mentioned it perfectly, a * n = a + a * (n - 1).
This code evaluates to true:
#include <iostream>
int main(){
int x = 9;
int j = x-1;
if(x - j+1 > 1)
std::cout << "Ehhhh???\n";
}
But this one to false:
#include <iostream>
int main(){
int x = 9;
int j = x-1;
if(x - (j+1) > 1)
std::cout << "Ehhhh???\n";
}
plus and minus operators has higher precedence than "<", I'm also using only one data type so there should be bo overflow. Why results are different?
This is really just a matter what value the 1 gets added to. Addition and subtraction have left to right associativity so we start from the left and work our way right.
x - j + 1
(9 - 8) + 1
1 + 1
2
Where as
x - (j + 1)
9 - (8 + 1)
9 - 9
0
Forces the addition to be attached to j instead of x-j so the second case is rightly false.
Since the precedence of arithmetic + and - is the same but the associativity is from left to right, the one without the parenthesis will first do the subtraction then the addition, i.e.:
x - j+1 ==2 //here the operation is performed from left to right,subtraction first then addition
x - (j+1)==0 //here the one inside the parenthesis will be done first,i.e addition first then subtraction
Mathematically you have 2 different expressions:
x - j + 1 is equal to x - ( j - 1 )
and
x - ( j + 1 ) is equal to x - j - 1
I want to make sure that all 3 conditions result in the same answer before executing a control block:
#include <iostream>
#include <cstdlib>
int main(){
///BUT THIS DOES NOT WORK!
if ( (2 + 2) == (1 + 3) == (4 + 0) ){
std::cout << "not executed" << std::endl;
}
return EXIT_SUCCESS;
}
Let's say those numbers are actually variables. This is what I have to do:
#include <iostream>
#include <cstdlib>
int main(){
int n1 = 2;
int n2 = 2;
int n3 = 1;
int n4 = 3;
int n5 = 4;
int n6 = 0;
int a = n1 + n2;
///this works
if ( (n3 + n4) == a && (n5 + n6) == a){
std::cout << "executed!" << std::endl;
}
return EXIT_SUCCESS;
}
question: why does my first example not work?
I can assign multiple variables the same value like this:
#include <iostream>
#include <cstdlib>
int main(){
int a,b,c,d;
a=b=c=d=9;
///prints: 9999
std::cout <<a<<b<<c<<d<<'\n';
return EXIT_SUCCESS;
}
hoping someone can explain why this method of evaluating doesn't work.
It recently came to my attention while writing an if statement that determines if an nxn array is a magic square or not.
(2 + 2) == (1 + 3) == (4 + 0)
First, (2 + 2) == (1 + 3) evaluates to true, because it really holds that 4 == 4.
Then, you're comparing true == (4 + 0). In this case, boolean values are casted to integers:
true -> 1
false -> 0
Therefore you're comparing 1 == 4, what results in false.
This portion results in a boolean or integer, 0 or 1:
(2 + 2) == (1 + 3)
So the rest of the expression looks like:
1 == (4 + 0)
or
0 == (4 + 0)
Neither of these are correct.
The only operator that takes three arguments is the foo ? bar : baz operator. Everything else takes one or two arguments.