This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 8 years ago.
This is a recursive function I wrote that can compute the ways of coin change, and it can work perfectly.
int cc(int n, int k)
{
if (n < 0 || k == 0)
return 0;
else if (n == 0)
return 1;
else
{
/*** WAY 1 : START ***/
s.stk[++s.top] = k;
int tmp = cc(n - d[k - 1], k);
s.top--;
return tmp + cc(n, k - 1);
/*** WAY 1 : END ***/
}
}
But, why it starts getting wrong answers if I change the code between two comments as follows:
/*** WAY 2 ***/
return (s.stk[++s.top] = k, cc(n - d[k - 1], k)) + (s.top--, cc(n, k - 1));
// |<----- A ----->| |<----- B ----->|
Aren't they equivalent?
P.S. Though it is not a good way to write like that (way 2), I just wonder why it can't work.
EDIT:
Though we don't know that whether A or B will do first, I tried to do some experiments.
The conclusion is that neither return A+B; nor return B+A; will get correct answers.
Read the "Undefined Behavior and Sequence Points" link given by #delnan for details. But the simplest explanation is that there is no sequence point between A + B. As such there is no guarantee as to which one of A and B would be evaluated first. That's why way 1 and way 2 are not equivalent.
In your case:
A = (s.stk[++s.top] = k, cc(n - d[k - 1], k))
B = (s.top--, cc(n, k - 1))
Now, the recursive calls to cc() will occur randomly, sometimes (decided at compile time not at runtime) on path A and sometimes on path B. As such, the order of calls is all screwed up.
You might want to add a print statement at the top of the function that would print the sequence number and the arguments on a new line. Then execute it with way 1 and way 2 using the same initial data. Collect the output in to two text files. Diff these two files and see for yourself where things go wrong.
Related
This question already has answers here:
Checking return value of a function without return statement
(3 answers)
Closed last month.
`
#include <stdio.h>
int k = 0;
int factorial (int x)
{
if (x == 1)
{
return 1;
}
k = x * factorial (x - 1);
}
int main()
{
printf ("Factorial of %d is: %d\r\n", 5, factorial(5));
return 0;
}
Factorial of 5 is: 120
I have been learning recursion for the last few days, and while working on the factorial of a given number using recursion, everything works fine, but the question I am having is that the above code, without any return statement, is printing the value 120 in the console for the factorial of 5.
Also, I am curious to know how, without any return statement except in the base condition of the factorial function, the recursive call is giving the correct answer.
if (x == 1)
{
return 1;
}
k = x * factorial (x - 1);
As per my understanding, the above line of code would execute like this:
k = 5 * factorial (5-1)
k = 4 * factorial (4-1)
k = 3 * factorial (3-1)
k = 2 * factorial (2-1)
k = 1 * factorial (1-1)
return 1; --> when x is 1
What value it will have in the factorial (x - 1) is something I don't understand. Because this factorial (x) function does not have any return statements.
If a function is defined to return a value but doesn't, and if an attempt is made to use the return value, this triggers undefined behavior in your program.
One of the ways undefined behavior can manifest itself is that the program appears to work properly. There is however no guarantee of this result, and in fact making seemingly unrelated changes to your code can change how undefined behavior can manifest itself.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I had this question in my exam a few weeks ago (Failed to answer it) and I wanted to know how to solve this kind of questions because I see they repeat themselves.
Write C program that gets Integers till -1 is inserted. if certain product of previously written numbers is equal to the last entered integer - the program will print it.
I know its pretty hard to understand but here are few examples :
(Typed order left to right)
1 -> 2 -> 3 -> 6 (Will print 2 * 3=6) -> 36 (Will print 2 * 3 * 6) -> -1
I can see that the problem is hard to do with arrays because of the memory limitation...
so I though of using "List" but ain't got idea how to.
I don't want a complete solution! I would like to get any hint on how to solve it in C (C# is also ok but C preferred).
Use a do-while cycle with condition and a counting sort.
https://en.wikipedia.org/wiki/Counting_sort
I wrote a raw program that does what you want with the exception that it always considers 1 as the product of previous numbers, and the same is true for numbers that were already entered. I leave you the challenge to fix the issue.
#include <stdio.h>
#define SIZE 10
void combo( int pro, int sum );
int n[SIZE], found, i;
int main() {
for( ; i < SIZE && scanf("%d", &n[i]) == 1 && n[i] != -1; i++) {
found = 0;
combo(1,0);
if( found ) printf("%d ", n[i]);
}
return 0;
}
void combo( int pro, int sum )
{
if( pro == n[i] ) found = 1;
for(int j = 0; j < i - sum && !found; j++) {
combo(pro * n[j], sum + 1);
}
}
n, found, i don't have to be global variables, but since combo could call itself lots of times, I thought it would have been a good idea to avoid giving it many arguments. I really don't know if it actually is a good idea.
Anyway, the program is a brute force. combo() will try every possible products of the elements of n.
For each j, combo will call itself generating a new loop, and for each index of this new loop there will be another recursive call generating a whole new loop, and so on.
combo stops to call itself when all the loops stop running.
A loop stops when either a matching product has been found or j reaches i - sum, where i is the current number of elements stored in the array minus 1, while sum represents the number of elements involved in the current product.
Every time, before to enter a loop, the function checks whether the current product matches the last number entered in the array.
If you know that the numbers are entered in ascending order you can optimize by swapping !found with pro < n[i].
I haven't done the math, but in case the input consists in a sequence of random integers, it may be more efficient to sort the array before to call combo in main.
I'm trying to write a recursive function in C to take the value of 3 to the power of another number. For example, if I enter 4, the program will return the value 81. And the following code is the answer for the question. But I can not clearly understand how the code can solve the problem. I mean that when 4 is passed to the function, the first 3 lines in the function body will be ignored, jump straight into the " // This line " . Then how is it from there will the program return the number 81. The function calls itself again with 3 passed? 3*three_power(3) ? I can not clearly understand that. Can someone explain? Sorry because it's a stupid question, I'm new to C.
#include <stdio.h>
int three_power(int power);
int main(){
int a=4;
int b=9;
printf("\n3 to the power of %d is %d", a, three_power(a));
printf("\n3 to the power of %d is %d", b, three_power(b));
return 0;
}
int three_power(int power){
if (power < 1){
return( 1 );
} else
return (3* three_power(power-1)); //This line
}
Yes, it takes the else branch on the first way through, which causes the recursive call for 4 - 1 which again takes the else branch, and so on down to the base case when power is 0 which just returns 1 (since 30 is 1).
The full chain is
3 * three_power(3) =
3 * (3 * three_power(2)) =
3 * (3 * (3 * three_power(1)) =
3 * (3 * (3 * (3 * three_power(0))) =
3 * (3 * (3 * (3 * (1)))) =
3 * 3 * 3 * 3 = 81
It's hard to visualize, but that's it.
You can of course single-step through this in a debugger to get a feeling for it, or just add a printf("power=%d\n", power); to the first line of three_power().
This is the essence of recursion.
In a mathematical sense, you can define the power of 3^n as 3 * 3^(n - 1), right? After all 3 to the anything is 3 multiplied times itself that number of times, right?
The recursion simply says that the answer to "What is 3 to the power?" Well it is 3 times three_power of power minus one. You need only handle the case when power is 0 and the returned value will be multiplied times 3 by the number of recursive calls made.
This is an excellent learning exercise, but you should prefer pow(3, power) because it is more efficient to calculate this way and you don't risk to exceed the maximum recursive call stack.
Consider writing the command flow showing each entry and exit for your example. Also the return on the else is a single line else. I will rewrite it showing the correct brackets.
1e. enter with value 4
2e. enter with value 3
3e. enter with value 2
4e. enter with value 1
5e. enter with value 0
5r. return 1
4r. return 3*5r = 3*1 = 3
3r. return 3*4r = 3*3 = 9
2r. retrun 3*3r = 3*9 = 27
1r. return 3*2r = 3*27 = 81
int three_power(int power)
{
if (power < 1)
{
return( 1 );
}
else
{
return (3* three_power(power-1)); //This line
}
}
Another way of putting it with a single return is
int three_power(int power)
{
int rtnval;
if (power < 1)
{
rtnval = 1;
}
else
{
rtnval = 3* three_power(power-1); //This line
}
return rtnval;
}
This is an example of recursion, which is similar to the mathematical concept of induction. For a given input, is invokes itself on a reduced input, then uses that result to produce the desired result.
A good way to understand how the function works is to start with the simplest case, verify that it works, then move on to the next simplest case, etc.
In this example, the simplest case is when power is 0. In that case, it immediately returns 1. So far so good.
Now consider what happens when power is 1. In this case, it returns 3 * power(0). In other words, it calls itself with a different input, then uses that result to produce a new result. We have already verified that power(0) returns 1. So in this case, it will return 3 * 1, which is just 3. Again, so far so good.
So what happens when power is 2? Well, it returns 3 * power(1). This results in multiple nested calls. We know that power(1) will return 3, so this case will return 9. Again, it's doing what we want.
More generally, when power is >= 1, it recursively calls itself to obtain the result for power - 1. This will in general result in a chain of calls which eventually return the desired result for power - 1. It then multiplies this by 3 and returns the result. This is 3 * (3 ** (power - 1)), which is just 3 ** power as desired.
You can confirm its correctness inductively. The basis case is when power is 0. This case is confirmed directly. Then, assuming it gives the correct result for power - 1, we can see that it will also give the correct result for power, from the recursive step. It will only fail if the result becomes large enough to overflow.
I would propose a more efficient recursion than f(n)=3*f(n-1).
It would be
// f(n) = 1 if n = 0
// f(n) = f(n/2)^2` if n is even
// f(n) = 3*f(n/2)^2 if n is odd
int power3(int n)
{
int m;
if (n == 0)
return 1;
else if (n % 2 == 0)
{
m = power3(n/2);
return m*m;
}
else
{
m = power3(n/2);
return 3*m*m;
}
}
This way the time complexity is reducing from O(n) to O(log(n)).
Hello getting better at C everyday, this is a example problem out of my textbook that generates fibonacci numbers and shows recursive functions. The program works but I just don't understand how... Specifically in parts (looper % 5), the whole functionfib and what printf(", %8ld", fib(looper)); is doing. Is it like saying fib() do x amount of times. If this problem is not easy to explain then could someone show me a easier way to understand how recursive functions work other then "towers of hanoi" example. Thanks.
NOTE: program is meant to handle up to 30 numbers others wise it starts to look ugly.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
long fib (long num);
int main(void)
{
int seriesSize;
printf("This program will print out a Fibonacci series.\n");
printf("How many many numers do you wnat? ");
scanf_s("%d", &seriesSize);
printf("First %d Fib numbers: \n", seriesSize);
for (int looper = 0; looper < seriesSize; looper++)
{
if (looper % 5)
{
printf(", %8ld", fib(looper));
}
else
{
printf("\n%8ld", fib(looper));
}
}
printf("\n");
return 0;
}
long fib(long num)
{
if (num == 0 || num == 1)
{
return num;
}
return (fib(num - 1) + fib(num - 2));
}
The idea behind the long fib(long num) function is that it mirrors the natural definition of the fibonacci sequence in that it is defined in terms of itself. That is, fib(n) is defined by fib(n-1) and fib(n-2). For example, fib(5) is fib(4)+fib(3).
The textbook has written the function in a recursive manner as described above. Note that this is not the most efficient way to implement a fibonacci function but it does logically make sense.
To understand it, it pays to trace through its execution with an example input. Take fib(3) for example. The first if statement doesn't trigger because num is not 0 or 1. Thus, it works out what fib(2) and fib(1) are, and adds them together. We know what fib(1) does - it returns 1 in the first if statement. Trace through fib(2) in a similar manner and you'll see that it returns 1. Thus, fib(3) will return fib(2)+fib(1)=2. You can extend this further - take fib(4). It will return fib(3)+fib(2), which we know are 2 and 1, hence fib(4) = 3.
This approach can be taken for most recursive functions - think of it as creating new instances of the fib() function which continually creates until it "bottoms out" at an end case (num == 1 or num == 0, in this case), and returns back up, filling in the answers until you get back to the function you started with, with the answer.
I was working on a code that is suppose to calculate the sequence:
a(n+2)=-2(n+1)+3a(n) a(0)=2 a(1)= -1
Unfortunately I cannot figure it out. I'm recently new at this (about a month) and I'm going to try best to do this on my own, but I will need some help. Thank you for whoever decides to help me.
#include <stdio.h>
int mysequence(int n)
{
if (n==0) return 2;
if (n==1) return -1;
if (n==2) return 8;
return (2 * mysequence(n+1) + mysequence(n+2))/3;
}
int main()
{
int n;
printf("Enter n = ");
scanf("%d", &n);
printf("%d\n",mysequence(n));
return 0;
}
I'm not sure how you came up with this line:
return (2 * mysequence(n+1) + mysequence(n+2))/3;
But that's not correct. For one thing, mysequence(n) would call mysequence(n+1) (and mysequence(n+2)), which would call mysequence(n+2), which would call mysequence(n+3), which would call mysequence(n+4), etc. - it should be easy to see that you'll never reach mysequence(0) or mysequence(1) (assuming n > 1), thus it would keep going forever, or at least until you run out of memory, since you're increasing instead of decreasing the parameter in subsequent calls.
Let's start from the beginning by first converting this:
a(n+2) = -2a(n+1) + 3a(n)
Into something that looks more like the code: (by subtracting 2 from each n+c)
(on the left side we'd like a(n), since the function takes the parameter n, not n+2)
a(n) = -2a(n-1) + 3a(n-2)
Now we simply need to put that in the code. Replace:
return (2 * mysequence(n+1) + mysequence(n+2))/3;
With
return -2 * mysequence(n-1) + 3 * mysequence(n-2);
Also, you don't really need to specifically cater for n == 2 - it will be handled correctly by the above statement.
The n will be more bigger until unlimited number when run your program.
I think you need change the function to :
a(n)=-2(n-1)+3a(n-2) a(0)=2 a(1)= -1
Replace n+2 with n. It will make n smaller until 1 and 0.
Then code will be:
int mysequence(int n)
{
if (n == 0) return 2;
if (n == 1) return -1;
return (-2 * mysequence(n - 1) + mysequence(n - 2)) / 3;
}
note: n >= 0
Look at the line return (2 * mysequence(n+1) + mysequence(n+2))/3 carefully and compare it with what you know about the sequence:
a(n+2)=-2(n+1)+3a(n).
They have nothing in common.
What you want is return (-2*mysequence(n-1) + 3*mysequence(n-2)).
As to why, well the coefficients should be clear enough, they are just copied from the definition. The reason we call the next level of recursion with n-1 and n-2 is also quite simple, observe:
a(n+2)=-2(n+1)+3a(n) -> substitute n for n-2 -> a(n)=-2(n-1)+3a(n-2).
Your recursive function is infinitely so! The value of n passed in is incremented in the recursive calls, but the base cases for the recursion assume they decrease.
You'll need what is called a change of variables. Let m = n + 2. So n = m - 2. Then the recurrence you've given becomes
a(m) = -2 * (m - 1) + 3 * a(m - 2)
Implement this as a recursive function. Since the value passed as the argument on the right hand side is now less than that the left, the small base case values will be reached for any m >= 0.