C++ Stack Fibinacci Hw Problem Clarification - c++

Hey Guys. I need help understanding my hw assignment. I am starting out in C++ and don't know that much. I do know the basics of a stack and fibonacci sequence. However I do not exactly understand the problem given to me and need not the code to solving the problem but help clarifying some steps. Here's the hw:
"By completing this project you will become familiar with using recursion and creating ADTs in C++.
Create an integer stack ADT (you may Modify the IntStack ADT given to you in the lecture notes) such that it has a maximum capacity of at least 256 elements. Also add whatever is needed such that it will print out its contents (left-to-right, with the top of the stack on the right) if it is printed to a C++ ostream - such as cout). This stack should be designed such that it will only hold meaningful values greater than zero. Values less than or equal to zero should be printed out as a '?'.
Write a recursive implementation of the Fibonacci sequence discussed in class. Also - create an instance of your stack ADT that persists between calls (it can't be a local variable), and at each step, push a non-meaningful value into it until the value at that stage is determined, then pop it off, and push in the determined value and print the entire stack before returning.
Your program should ask for the position N in the Fibonacci sequence to be determined and then it should output the result of the function call. Example output (including the output from your recursive function) follows:
Enter the position in the Fibonacci sequence to determine: 5
?-?-?-1
?-?-?-1
?-?-2
?-?-1
?-3
?-?-1
?-?-1
?-2
5
Fibonacci(5) = 5
What exactly is the output here? Is it printing out the stack as it calculates the 5th position? also Any ideas on how to implement the Fibonacci into a stack in C++? Should these values be stored in array, list or it doesn't matter? I'm a noob so any help would be much appreciated. Thanks

Yes, it's calculating 5th fibonacci number (which happens to be 5, that's a bit confusing), but look at what you calculate when you call fibonacci(5), assuming the following code for fibonacci:
int fibonacci(int n) {
if (n <= 1) return n;
else if (n == 2) return 1;
else return fibonacci(n-1) + fibonacci(n-2);
}
here are the function calls to calculate fibonacci(5):
f(5)
-> f(4)
-> f(3)
-> f(2)
-> f(1)
-> f(2)
->f(3)
-> f(2)
-> f(1)
If you look at this as a binary tree, the output they gave you was a post-order tree traversal, with the amount of ? being the depth of that stack, and the number being the value of that node.
So just do what the function does and every time you see return, write what you return (with the ?'s before it):
The first function that returns is the first f(2), at depth 4: print ?-?-?-1
The second return is the f(1) below it: print ?-?-?-1
The third return is the parent of f(2) and f(1), which has depth 3 and value f(2)+f(1)=2: print ?-?-2
And so on until you return f(5) at depth 0 and value 5

Beak your entire problem into smaller parts which can be solved/implemented by themselves. In this case there are two main parts:
Stack -- Implement a standard stack class according to the details given in the question. It may help to list them all in point form.
Fibonacci -- Use the stack class to generate the Fibonacci series recursively. The stack is your storage mechanism for this exercise.
The example output ?-?-?-1 can be understood as the following stack operations:
push 0
push 0
push 0
push 1
print

I leave printing the stack to you and address the confusing part of using the stack to store marker ("the non meaningful" number) and result. Here is the partial pseudo code:
procedure fib(n)
push a marker (say a zero) to a global stack
if n is 1 or 2 then
result = you_know_what
else
calculate fib(n-1)
pop the stack ==> fib_n_minus_1
calculate fib(n-2)
pop the stack ==> fib_n_minus_2
result = fib_n_minus_1 + fib_n_minus_2
endif
pop the marker off the stack and discard
push the result into the stack
print the stack
end fib
The key to note here is fib() does not return a value. Instead, it pushes the return value into a global stack.

Related

recursive function in vector passed by reference

i am learning data structure on c++ and i have come through one thing which is hard for me to understand or get concept.
I am just putting question to give better context.
https://leetcode.com/problems/frequency-of-the-most-frequent-element/
The frequency of an element is the number of times it occurs in an array.
You are given an integer array nums and an integer k. In one operation, you can choose an index of nums and increment the element at that index by 1.
Return the maximum possible frequency of an element after performing at most k operations.
Example 1:
Input: nums = [1,2,4], k = 5
Output: 3
Explanation: Increment the first element three times and the second element two times to
make nums = [4,4,4].
4 has a frequency of 3.
this is the code given to complete:
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
}
};
i want to solve this problem by recursive first but my problem here is that the function is getting reference of a vector as a parameter so if i change the value inside the function, it will change the original vector.
I am not able to think how can i make different recursion with different choices because it is not pass by value.
Any help please !!

Some mysterious stack mechanism in C++

While learning how to write quick sort I came across a certain implementation that is very unclear for me. Here is the beginning of it:
void quick_sort_iterative(int start, int end)
{
range stack[32]; // 1. why 32? why not 2? why not 1024? what is it?
range * s = stack; // 2. just a simple pointer = an array?
s->start = start; // 3. are these two values currently on top of the stack?
s->end = end;
s++; // 4. how does it work? it's pushing something on the stack?
// sort as long as there are any ranges [start, end] to sort left
while (s > stack) // 5. comparing a pointer and an array and it works?
Could someone please explain me those 5 things? :) Thank you.
Here is the entire code (the last one on the page, with the descriptions):
code
So. Presumably range is some object with two integer parameters start and end. I can't tell much more than that.
For whatever reason, the designers of the algorithm believe that they won't need more than 32 fake stack frames.
The array decays to a pointer. You can think of this as &stack[0].
s->start is currently the same as s[0].start.
s now points to &stack[1].
The array decays to a pointer. So that is true as long as s doesn't point to &stack[0].
Maybe just a number picked from their nether region, or perhaps arrived at through careful examination of the maximum stack depth of the algorithm. I'm guessing the former.
Any array variable will naturally decay to a pointer when used in a context that requires a pointer.
If you consider the first element of the "stack" array to be the top, then yes.
Given the assumption in 3 then incrementing the pointer would indeed be moving to the next element down on the stack.
See 2. Presumably the loop is decrementing s and they want to stop when it reaches the top of the stack again.

Behaviour of static variables in recursion

I am talking with reference to C++.
I know that if an int is declared as static in recursion, its value is not reinitialized in stack-recursion call and the present value is used.
But if a stack becomes empty(or a recursion computation is complete) and then the recursion is called again, will it use the same static value as initialized in first stack call??
I will explain my problem in detail.
I am trying to code level order traversal in spiral form.
1
/ \
2 3
/ \ / \
7 6 5 4
Level order traversal in spiral form will give output 1 2 3 4 5 6 7.
void LevelSpiral(node* root, int level)
{
static int k = level%2;
if(root==NULL)
return;
if(level==1)
{
printf("%d ",root->val);
}
else
{
if(k==0)
{
LevelSpiral(root->left,level-1);
LevelSpiral(root->right,level-1);
}
else
{
LevelSpiral(root->right,level-1);
LevelSpiral(root->left,level-1);
}
}
}
void LevelOrderSpiral(node* root)
{
for(int i=1;i<=maxheight;i++)
LevelSpiral(root,i);
}
LevelOrderSpiral function makes separate LevelSpiral-call for each i. But throughout the code it always uses k=1(which is initialized in the first LevelSpiral-call with i=1) and prints the output as 1 3 2 4 5 6 7.
Shouldn't it print 1 2 3 4 5 6 7 as the function stack is reinitialized for every i?
You need a static variable for it's value to be retained between calls, or from one call to the next recursive call.
Furthermore, recursion wouldn't be the first tool I reach for a breadth-first traversal. I would use a queue of node (safe) pointers (or reference wrappers or whatever). Put the root node in the queue, then loop until the queue is empty removing the front element and enqueueing all of it's child nodes and do what you want with the recently removed element.
Regarding your implementation, you are alternating between going to the left first and going to the right first. level always equals 1 at the row before the one you want to print, so you always traverse your printing row from right to left. You'll see bigger shufflings of the nodes when you have a deeper tree. Draw a sample tree on paper and draw the navigations on it as you follow your code by hand.
I know that if an int is declared as const in recursion, its value is not reinitialized in stack-recursion call and the present value is used.
No, that’s wrong. const has got nothing to do with recursion or reentrancy.
But if a stack becomes empty(or a recursion computation is complete) and then the recursion is called again, will it use the same const value as initialized in first stack call??
A const is a normal (albeit unmodifiable) variable: it is reinitialised whenever the initialisation statement is executed, i.e. on every function call. This is the same for any non-static variable.
static local variables exhibit the behaviour you are describing: they are only executed once, at the first call of that function, and, importantly, they are not reinitialised even after the call stack is “emptied”. It makes no difference whether the function is called repeatedly from outside, or recursively.

Recursive function causes stack overflow

I have the following task:
Write a program that asks for a number and a power. Write a recursive
function that takes the number to the power. For example, if the
number is 2 and the power is 4, the function will return 16.
I wrote a program and there are no errors when I compile it, but when I start the program and enter a value gives an error saying "Stack Overflow". I suppose my recursive function became infinite but I have no idea how to write it in other way.
This is my code:
#include <iostream>
using namespace std;
int powpow(int number);
int main(){
cout<<"Enter number:";
int x;
cin>>x;
cout<<"The result of ("<<x<<" * "<<x<<") * "<<x*x<<" is: "<<powpow(x);
system("pause");
return 0;
}
int powpow(int number){
int result = number*number;
return powpow(result);
}
You have no terminating condition for your recursion, so it runs forever.
It sounds like maybe you don't have a good grasp of recursion, so I'd like to start with something a little simpler, the Fibonacci sequence.
Any time we define a function in terms of recursion, we need to first define a base case(s). In the case of Fibonacci, we have 2 base cases:
F(0) = 0
F(1) = 1
That says, in english, "F of 0 is 0, F of 1 is 1". Or even more simply, if we pass 0 to function F, we will get 0 back. If we pass 1, we will get 1 back.
Once we have the base cases defined, then we need to look for a recurrence relation. In the case of Fibonacci, we have the following recurrence:
F(n) = F(n-1) + F(n-2)
So for n >= 2, we can use the above recurrence. Why? Well, lets try it for n = 2.
F(2) = F(n-1) + F(n-2)
= F(1) + F(0)
= 1 + 0
= 1
So now we know that the answer to F(2) is 1. And what's more, we can now compute the answer to F(3). Why? Well, what do we need to compute F(3)? We need F(2) and F(1). We now have both of those answers since F(1) is a base case, and we just solved F(2) above.
So, now let's try to write a piece of pseudo code to solve F.
function F(int n) {
// handle base cases
if (n equals 0)
return 0
if (n equals 1)
return 1
// recurrence
return F(n-1) + F(n-2);
}
Note that in a recursive function, we always handle the base cases at the beginning of the function. We cannot define this recurrence if we don't have base cases in place, otherwise, we will have no terminating condition for our recurrence. So that's why you always put the base cases at the beginning of the function.
Now, given the above explanation, another good exercise would be to write a recursive function for the factorial function. So, follow these steps:
1. Define the base case (use wikipedia article for hints).
2. Define recurrence in terms of base case
3. Write pseudo code to solve the recurrence, and be sure to put base case(s) at beginning of function, and recurrence at end.
Once you grasp these steps, then moving on to the power recurrence should make much more sense to you.
Your function
does not what it should do
has no termination condition
Try to think about this: How can your function return x^y when it only takes one number as a parameter. Then, think about how you raise number to a power and the implementation should be obvious.
Recursive routines always need a "trivial" or "base" case. Think about what you wrote, pass in 1 for x, what will the stop the recursion?
powpow(1)
result = 1*1
call powpow(1)
result = 1*1
call powpow(1)
result = 1*1
call powpow(1)
adinfinitum (or until you exeed the stack)

How to implement tail calls in a custom VM

How can I implement tail calls in a custom virtual machine?
I know that I need to pop off the original function's local stack, then it's arguments, then push on the new arguments. But, if I pop off the function's local stack, how am I supposed to push on the new arguments? They've just been popped off the stack.
I take it for granted that we're discussing a traditional "stack-based" virtual machine here.
You pop off the current function's local stack preserving the still-relevant parts in non-stack "registers" (where the "relevant parts" are, clearly, the argument for the forthcoming recursive tail call), then (once all of the function's local stack and arguments are cleaned up) you push the arguments for the recursive call. E.g., suppose the function you're optimizing is something like:
def aux(n, tot):
if n <= 1: return tot
return aux(n-1, tot * n)
which without optimization might produce byte-code symbolically like:
AUX: LOAD_VAR N
LOAD_CONST 1
COMPARE
JUMPIF_GT LAB
LOAD_VAR TOT
RETURN_VAL
LAB: LOAD_VAR N
LOAD_CONST 1
SUBTRACT
LOAD_VAR TOT
LOAD_VAR N
MULTIPLY
CALL_FUN2 AUX
RETURN_VAL
the CALL_FUN2 means "call a function with two arguments". With the optimization, it could become sometime like:
POP_KEEP 2
POP_DISCARD 2
PUSH_KEPT 2
JUMP AUX
Of course I'm making up my symbolic bytecodes as I go along, but I hope the intent is clear: POP_DISCARD n is the normal pop that just discards the top n entries from the stack, but POP_KEEP n is a variant that keeps them "somewhere" (e.g. in an auxiliary stack not directly accessible to the application but only to the VM's own machinery -- storage with such a character is sometimes called "a register" when discussing VM implementation) and a matching PUSH_KEPT n which empties the "registers" back into the VM's normal stack.
I think you're looking at this the wrong way. Instead of popping the old variables off the stack and then pushing the new ones, simply reassign the ones already there (carefully). This is roughly the same optimization that would happen if you rewrote the code to be the equivalent iterative algorithm.
For this code:
int fact(int x, int total=1) {
if (x == 1)
return total;
return fact(x-1, total*x);
}
would be
fact:
jmpne x, 1, fact_cont # if x!=1 jump to multiply
retrn total # return total
fact_cont: # update variables for "recursion
mul total,x,total # total=total*x
sub x,1,x # x=x-1
jmp fact #"recurse"
There's no need to pop or push anything on the stack, merely reassign.
Clearly, this can be further optimized, by putting the exit condition second, allowing us to skip a jump, resulting in fewer operations.
fact_cont: # update variables for "recursion
mul total,x,total # total=total*x
sub x,1,x # x=x-1
fact:
jmpne x, 1, fact_cont # if x!=1 jump to multiply
retrn total # return total
Looking again, this "assembly" better reflects this C++, which clearly has avoided the recursion calls
int fact(int x, int total=1)
for( ; x>1; --x)
total*=x;
return total;
}