In this code can you please explain what is happening after the draw(n -1) function - recursion

#include <stdio.h>
#include <cs50.h>
void draw(int n);
int main(void)
{
int height = get_int("number:");
draw(height);
}
void draw(int n)
{
if(n <= 0)
{
return;
}
draw(n - 1);
for(int i = 0 ; i < n ; i++)
{
printf("#");
}
printf("\n");
}
Iam learing recursion topic, suppose the user input 4 when the compiler completes the if part the value of n is '0' and returning when i debug , but then the for loop starts the value of 'n' becomes '1' and also 'i' doesn't change it constantly 0 why is that iam expected n becomes 0 after the if draw(n - 1) completes.

I will try to make this explanation as simple as I can. First things first, To begin with, when using recursion, you would be noticing the calling of a method within itself with a different argument. In your case it is the draw method.
Now each time, a draw method is called inside another draw method, the outer method(in this case the draw that is called first) stops its flow of execution till the completion of the inner draw.
So when you called draw(4), it ran all the code till it reached line 5 in draw method, and called draw(3). Your for loop of draw(4) is not executed yet. This will continue till draw(1) calls a draw(0). At this stage, draw(0) will return out and the draw(1) will continue its for loop from where it left. So you would find that here n=1, leading to the first print of # and then a new line after it. Once the operation completes in here, it continues with where it left for draw(2). Which is the for loop in draw(2) where the value of n=2. And here it does two print of # and then a new line. This continues.
Now for the question why i is always 0, it is to do with what we call scopes in programming, you can see that each time the i is declared fresh in the loop and assigned a value 0. This means, each time a for loop is hit, the value of i is reinitialised to 0. If you had a global var i out side of your draw method, you would have had the value of i being retained.
I did try my best to put things in as simple form as possible but feel free to let me know if you needed more clarity.

Related

Calculating number of nodes in BST using recursion c++

I'm trying to find the number of nodes in a BST using recursion. Here is my code
struct Node{
int key;
struct Node* left;
struct Node* right;
Node(){
int key = 0;
struct Node* left = nullptr;
struct Node* right = nullptr;
}
};
src_root is the address of the root node of the tree.
int BST::countNodes(Node* src_root, int sum){
if((src_root==root && src_root==nullptr) || src_root==nullptr)
return 0;
else if(src_root->left==nullptr || src_root->right==nullptr)
return sum;
return countNodes(src_root->left, sum + 1) + countNodes(src_root->right, sum + 1) + 1;
}
However my code only seems to work if there are 3 nodes. Anything greater than 3 gives wrong answer. Please help me find out what's wrong with it. Thanks!
It is a long time ago since I made anything in C/C++ so if there might be some syntax errors.
int BST::countNodes(Node *scr_root)
{
if (scr_root == null) return 0;
return 1 + countNodes(scr_root->left) + countNodes(scr_root->right);
}
I think that will do the job.
You have several logical and structural problems in your implementation. Casperah gave you the "clean" answer that I assume you already found on the web (if you haven't already done that research, you shouldn't have posted your question). Thus, what you're looking for is not someone else's solution, but how to fix your own.
Why do you pass sum down the tree? Lower nodes shouldn't care what the previous count is; it's the parent's job to accumulate the counts from its children. See how that's done in Casperah's answer? Drop the extra parameter from your code; it's merely another source for error.
Your base case has an identically false clause: src_root==root && src_root==nullptr ... if you make a meaningful call, src_root cannot be both root and nullptr.
Why are you comparing against a global value, root? Each call simply gets its own job done and returns. When your call tree crawls back to the original invocation, the one that was called with the root, it simply does its job and returns to the calling program. This should not be a special case.
Your else clause is wrong: it says that if either child is null, you ignore counting the other child altogether and return only the count so far. This guarantees that you'll give the wrong answer unless the tree is absolutely balanced and filled, a total of 2^N - 1 nodes for N levels.
Fix those items in whatever order you find instructive; the idea is to learn. Note, however, that your final code should look a lot like the answer Casperah provided.

Understanding Recursion with Merge sort

I see some of the posts to understand merge sort. I know recursive methods maintains stack to hold values. (my understand was return statement result will be in stack )
private int recur(int count) {
if (count > 0) {
System.out.println(count);
return count + recur(--count); // this value will be in stack.
}
return count;
}
I am confusing in merge sort how stack is maintaining here.
private void divide(int low, int high) {
System.out.println("Divide => Low: "+ low +" High: "+ high);
if (low < high) {
int middle = (low + high) / 2;
divide(low, middle); // {0,7},{0,3}, {0,1} ;
divide(middle + 1, high); // {0,0}; high = 1; // 2nd divide
combine(low, middle, high);
}
}
Is stack for all local variables?
When 2nd recursive method calls, 1st recursive will also join?
How stack are maintained in such cases?
You only have to know that a statement needs to finish and return and that you call divide or combine from divide works the same. Both need to finish before the next line of code can be executed or, if there are no more lines, the function returns. Yes, it's done with stack but it's really not important.
The state of the waiters variables low, high and middle is only the current invocations bindings so they don't get mixed with other invocations.
Every time you nest a new call it gets it's own variables and each need to finish. When the low-middle is finished it calls middle+1-high and when that finished combine. Those calls will do the same so you will have deeper nesting and how the call structure will be visited is like like a binary tree structure with the leafs being low == high (one element).
A word of advice. When looking at recursive code try doing it from leaf to more complex tree. eg. try it out with base case first, then the simplest of default case. eg.
1 element array: does nothing
2 element array: -> 1 element array (see 1.), 1 element array, combine
4 element array: -> 2 element array (see 2.), 2 element array, combine
Notice that the 2. you know both recursive calls won't do anything and combine will do perhaps a swap. The 3. does 2. twice (including the swap) before combine that will merge 2 2 element arrays that are sorted. You are perhaps looking at it the other way, which requires you to halt 3. to do 2. that halts it and does 1., then the next 1, then back to 2. to do the text that has two 1s... It needs pen and paper. Looking at it from leaf to root using what you have learned of it so far lets you understand it much easier. I do think functional recursion is easier to grasp than mutating structures like your merge sort. eg. fibonacci sequence.

how to rewrite the recursive solution to iterative one

The problem is derive from OJ.
The description is :
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
I write small snippet about MinMax problem in recursion. But it is slow and I want to rewrite it in a iterative way. Could anyone help with that and give me the idea about how you convert the recursive solution to iterative one? Any idea is appreciated. The code is showed below:
public int getMoneyAmount(int n) {
int[][] dp = new int[n + 1][n + 1];
for(int i = 0; i < dp.length; i++)
Arrays.fill(dp[i], -1);
return solve(dp, 1, n);
}
private int solve(int[][] dp, int left, int right){
if(left >= right){
return 0;
}
if(dp[left][right] != -1){
return dp[left][right];
}
dp[left][right] = Integer.MAX_VALUE;
for(int i = left; i <= right; i++){
dp[left][right] = Math.min(dp[left][right], i + Math.max(solve(dp, left, i - 1),solve(dp, i + 1, right)));
}
return dp[left][right];
}
In general, you convert using some focused concepts:
Replace the recursion with a while loop -- or a for loop, if you can pre-determine how many iterations you need (which you can do in this case).
Within the loop, check for the recursion's termination conditions; when you hit one of those, skip the rest of the loop.
Maintain local variables to replace the parameters and return value.
The loop termination is completion of the entire problem. In your case, this would be filling out the entire dp array.
The loop body consists of the computations that are currently in your recursion step: preparing the arguments for the recursive call.
Your general approach is to step through a nested (2-D) loop to fill out your array, starting from the simplest cases (left = right) and working your way to the far corner (left = 1, right = n). Note that your main diagonal is 0 (initialize that before you get into the loop), and your lower triangle is unused (don't even bother to initialize it).
For the loop body, you should be able to derive how to fill in each succeeding diagonal (one element shorter in each iteration) from the one you just did. That assignment statement is the body. In this case, you don't need the recursion termination conditions: the one that returns 0 is what you cover in initialization; the other you never hit, controlling left and right with your loop indices.
Are these enough hints to get you moving?

Print singly linked list in reverse order

Okay, this was the bonus question in CMPS 280's test at southeastern Louisiana Univ. Print singly linked list in reverse in three lines. Any ideas?
C implementation of your bonus question, in three lines:
#include <stdio.h>
struct node {
int data;
struct node* next;
};
void ReversePrint(struct node* head) {
if(head == NULL) return;
ReversePrint(head->next);
printf("%d ", head->data);
}
int main()
{
struct node first;
struct node second;
struct node third;
first.data = 1;
second.data = 2;
third.data = 3;
first.next = &second;
second.next = &third;
ReversePrint(&first); // Should print: 3 2 1
printf("\n");
return 0;
}
If you are allowed to use another Data Structure, then use a Stack.
Step 1: Traverse the linked list from the head node and put the key into the stack, till you reach the last node. This will take O(n) time.
Step 2 : Pop the elements out from the stack. This will take O(1) time.
Therefore, code will be
while(head != null){
stack.push(head.val);
head = head.next;
}
while(stack.isEmpty() != true){
stack.pop();
}
Generally, when asking for help on SO, you should always try to do the problem yourself first. Then, if you are stuck, come here with what you have done so far and clearly show what your problem is to maximize your chances of getting help.
How to ask a good question on SO
However, since it is a past exam question and my answer wont help you cheat :), here's pseudo-code how you can do it recursively:
reversePrint(head)
if head is null then return // Line 1: base case
reversePrint(head.next) // Line 2: print the list after head
print(head.data) // Line 3: print head
Below are the different ways of doing it. Complete source code can be at found the hyperlinks below.
1) Printing using extra memory : https://www.geeksforgeeks.org/print-reverse-linked-list-using-stack/
2) Printing using recursion : https://www.geeksforgeeks.org/print-reverse-of-a-linked-list-without-actually-reversing/
3) Printing by modifying original list - i.e. first reverse the list and then print from start.
Source Code for reversing list : https://www.geeksforgeeks.org/reverse-a-linked-list/
4) Printing without using extra space or modifying original list : https://www.geeksforgeeks.org/print-reverse-linked-list-without-extra-space-modifications/
5) Printing using Carriage return (“r”) : https://www.geeksforgeeks.org/an-interesting-method-to-print-reverse-of-a-linked-list/
Below is my iterative Java solution without stacks. I suppose the space complexity is still O(n) because the length of the StringBuilder grows linearly with the number of items in the list. However, we can get away without using a stack (either the data structure or the recursive call stack), neither of which is necessary if all we're doing is printing the elements to console. Also, the iterative stack solutions use two loops whereas this method only requires one. Finally, the time complexity is still O(n), which is much better than the quadratic algorithm by Geeks for Geeks referenced in another answer.
void printInReverse(ListNode head) {
StringBuilder sb = new StringBuilder();
ListNode n = head;
while (n != null) {
sb.insert(0, "<-" + n.data);
n = n.next;
}
System.out.println(sb.toString());
}

Basic PIC Programming issues

I am writing PIC code in C and encountered the following problems:
When I write my delay as _delay_ms(500), my code doesn't compile, it says it didn't recognize this instruction. I am using MPLAB.
I want to write a program that would count how many time the push button is pressed then return that value and display it using LED's. I know how to display it, but not how to make the program to wait for the push of the push button on the pickit.
main()
{
TRISA=0;//Sets all ports on A to be outputs
TRISB=1;//Sets all ports on B to be inputs
for(;;){
if(PORTBbits.RB0==1){//When the button is pressed the LED is off
PORTAbits.RA1 =0;
count=count+1;
}
else{
PORTAbits.RA1=1;
count = count +1;
}
if (count > 20){//if count =20 aka 20 button presses the LED turns on
PORTAbits.RA0=1;
}
else{
PORTAbits.RA0=0;
}
}
}
There are a few issues:
Assuming you're using a PIC24 or a dsPIC, you need to include libpic30.h
Before you include libpic30.h you need to #define FCY to be your instruction rate so that the delay takes the correct number of cycles. See the comments in the libpic30.h file for details.
The function is __delay_ms not _delay_ms. Note that there are two underscores at the beginning.
The name is all lower case, not Delay_ms as in your comment.
You need to add delay in your code when you detect a key is pressed. As you are saying the _delay_ms(500) is not recognized, You can try something like following:
unsigned char x;
// Just waste a few cycles to create delay
for (x = 0; x < 100; x++)
{
// No operation instruction
Nop();
}
You can create your own delay function with specific number of iterations of this for loop. Measure the exact delay created by this function using a profiler if you need. IMO any arbitrary delay, like say 100 iterations as stated above shall work.

Resources