how does a function with 2 recursive call works? - c++

I have been trying really hard to understand this question.
Question is:- In a mathematics class, Teacher ask Alice to find the number of all n digit distinct integers which is formed by the two distinct digits a and b but there is a rule to form n digit integer.
Rule: She has to form n digit integer by using two digits a and b without consecutive b.
Input Format:-
The first line contains T, the number of test cases. Further T lines contains the value n which is the number of digit in the integer.
Code:-
#include<bits/stdc++.h>
using namespace std;
void classAssignment(int n,string ans, int &count){
if(ans.length()==n){
cout<<ans<<endl;
count++;
return;}
classAssignment(n,ans+"a",count);
if(ans.length()==0 || ans.at(ans.length()-1)!='b'){
classAssignment(n,ans+"b",count);}
}
int main() {
int t;
cin>>t;
for(int i=0;i<t;i++){
int count=0;
int n;
cin>>n;
classAssignment(n,"",count);
cout<<"Total paths are "<<count<<endl;}
return 0;}
Output:
aaa
aab
aba
baa
bab
Total paths are 5
Now I am unable to understand how this code generates this output?? How are these 2 recursive calls are working to get this output??

That's what the debugger is for my friend. The debugger allows you to step through every line of code one by one, and thus, helps us to understand code and also point out errors.
So basically to understand what the recursive calls are doing, let's take an example of the first call. Now the function is first invoked by:
classAssignment(n, "", count);
Remember, ans = "" right now.
Now, the first recursive call:
classAssignment(n,ans+"a",count);
Now when this function is called, ans = "a" (for the recursive function). Now the recursive function calls the above line again, and passes ans + "a" (which means "a" + "a" = "aa") as one of the 2 arguments. Now, ans.size() == n(2), so it is printed out, and both the recursively called functions return, one after the other. Something like this goes for the second recursive call as well.
And if you're wondering for the count variable, all recursive/non-recursive are modifying the same variable, as it's passed by reference.
It may still not be clear but that's the best I could give :). For more clear understanding, you must use the debugger.
By the way, you should really look up to
the reasons Why should I not #include <bits/stdc++.h>?

Related

Array Function. Would appreciate a little clarification

I have a question regarding a school lab assignment and I was hoping someone could clarify this a little for me. I'm not looking for an answer, just an approach. I've been unable to fully understand the books explanations.
Question: In a program, write a function that accepts three arguments: an array, the size of the array, and a number n.
Assume that the array contains integers. The function should display
all of the numbers in the array that are greater than the number n .
This is what I have right now:
/*
Programmer: Reilly Parker
Program Name: Lab14_LargerThanN.cpp
Date: 10/28/2016
Description: Displays values of a static array that are greater than a user inputted value.
Version: 1.0
*/
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
void arrayFunction(int[], int, int); // Prototype for arrayFunction. int[] = array, int = size, int = n
int main()
{
int n; // Initialize user inputted value "n"
cout << "Enter Value:" << endl;
cin >> n;
const int size = 20; // Constant array size of 20 integers.
int arrayNumbers[size] = {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; // 20 assigned values for the array
arrayFunction(arrayNumbers, size, n); // Call function
return 0;
}
/* Description of code below:
The For statement scans each variable, if the array values are greater than the
variable "n" inputted by the user the output is only those values greater than "n."
*/
void arrayFunction(int arrayN[], int arrayS, int number) // Function Definiton
{
for (int i=0; i<arrayS; i++)
{
if (arrayN[i] > number)
{
cout << arrayN[i] << " ";
cout << endl;
}
}
}
For my whole answer I assume that this:
Question: In a program, write a function that accepts three arguments: an array, the size of the array, and a number n. Assume that the array contains integers. The function should display all of the numbers in the array that are greater than the number n .
is the whole assignment.
void arrayFunction(int[], int, int); is probably the only thing you could write. Note however that int[] is in fact int*.
As others pointed out don't bother with receiving input. Use something along this line: int numbers[] = {2,4,8,5,7,45,8,26,5,94,6,5,8};. It will create static array for you;
You have parameter int n but you never use it.
You are trying to send variable to the function arrayFunction but I can't see definition of this variable!
Use something called rubber duck debugging (google for it :) ). It will really help you.
If you have some more precise question, ask them.
As a side note: there are better ways of sending an array to the function, but your assignment forces you to use this old and not-so-good solution.
Would you use an if else statement? I've edited my original post with the updated code.
You have updated question, then I update my answer.
First and foremost of all: do indent your code properly!!!
If you do that, your code will be much cleaner, much more readable, and it will be much easier understandable not only for us, but primairly for you.
Next thing: do not omit braces even if they are not required in some context. Even experienced programmers only rarely omit them, so as a beginner you should never do so (as for example with your for loop).
Regarding if-else statement the short answer is: it depends.
Sometimes I would use if (note: in your case else is useless). But other times I would use ternary operator: condition ? value_if_true : value_if_false; or even a lambda expression.
In this case you should probably settle for an if, as it will be easier and more intuitive for you.
Aside from the C++ aspect, think about the steps you need to do to figure out if a number is greater than a certain value. Then do that for all the numbers in the array, and print out the number if it's greater than n. Since you have a 'for' loop, it looks like you already know how to do a loop and compare numbers in C++.
Also, it looks like in your arrayFunction you are trying to input values? You can't input a whole array's worth of values in a single statement like you appear to be trying (also, 'values' is not the name of any variable in arrayFunction, so that would not be recognized when you try to compile it).

random numbers within a function c++

I am trying to better use and understand functions and in this case I need to figure out how to make this function in particular return 2 different random numbers.I have set up the ctime and can successfully call my function and make my variable(message) equal the random number but when I call it again and ask it to print out the newest random number they are both the same.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int RandomNumberGen (int x);
int main()
{
srand(unsigned(time(0)));
int Ran;
int message;
message = RandomNumberGen (Ran);
cout << "Number 1 " << message << endl;
message = RandomNumberGen (Ran);
cout << "Number 2 " << message << endl;
return 0;
}
int RandomNumberGen (int Ran)
{
unsigned int RandomNum = 0;
RandomNum = rand()%8 + 4;
return RandomNum;
}
As you can see I set the function to output a random number and write it on screen and then I call the same function again and write that one on screen(write the second # on screen).Yet every time I call the function both numbers are written on the screen as the same even though I am generating a random number each time.
I know this is a simple and easy task but please let me know if what I am attempting to do is possible or do I need another separate function for the 2nd number.
My end goal is to base a lot of events and things off of one random number function so I can essentially call the function for a random number and then let it determine what happens next.
I placed in the code as you asked.I hope this is what you meant.I appreciate all the help and am very grateful for the answers.I plan to be using this more so I will be sure to get it right for you guys!
You called srand in the function RandomNumberGen, which is called multiple times. That's wrong, srand should be called only once, try put it in main instead.
Or better, instead of the C library crandom functions, use the methods in random if that's available.
Take a look at this question and particularly the answer. It should clarify some things about srand() and rand()
I quote the answer:
Seed is usually taken from the current time, which are the seconds, as in time(NULL), so if you always set the seed before taking the random number, you will get the same number as long as you call the srand/rand combo multiple times in the same second.
Basically what you should do, is call srand() only once at the beginning of your application and not in the function. Because your function will be called twice at a very short interval. Almost all the time in the same second. Generating the same starting sequence for the rand() function
you shouldn't seed the random number generator with each call, but only once. your two calls to the function probably execute so fast that the value of time(null) is still the same, and the same seed will produce the same pseudo random sequence.
(btw., you should use null or NULL, not 0 for a null pointer, and you do not use the parameter you pass to your randomnumbergen function, so you could just remove it entirely.)

3-way mergesort stackoverflow error in c++

hi guys can anyone tell me what's wrong with my 3-way mergesort code?the code I wrote can only sort 4 numbers if you give it more than 4 numbers(by changing size) it ends up with stack overflow error,here is the code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int size=4;
vector <int> s(size);
void merge(int,int,int);
void mergesort(int,int);
int main(){
for(int i=0;i<size;i++){
cout<<"enter number "<<i+1<<":";
cin>>s.at(i);
}
system("CLS");
cout<<"here are the unsorted numbers:\n";//prints the input values so U can see'em
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
mergesort(0,size-1);//calls mergesort
cout<<"\nhere are the sorted numbers:\n";
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
cin.get();
cin.get();
return 0;
}
void merge(int low,int one_third,int high){
int i=low;
int j=one_third+1;
int k=0;
int length=(high-low)+1;
vector <int> u(length,0);
if(k<length){
while((i<=one_third)&&(j<=high)){
if(s.at(i)<=s.at(j)){
u.at(k)=s.at(i);
i++;
k++;
}//end for
else{
u.at(k)=s.at(j);
j++;
k++;
}//end elseif
}//end while
if(j>high)
while(i<=one_third)
{
u.at(k)=s.at(i);
i++;
k++;
}
if(i>one_third)
while(j<=high)
{
u.at(k)=s.at(j);
j++;
k++;
}
for(int n=low;n<k;n++)
s.at(n)=u.at(n);
}
}//end if
void mergesort(int low,int high){
if(low<high){
int one_third=(high-low)/3;//division,it's 3-way mergesort so obviously it's divided by 3
int two_third=2*one_third;
mergesort(low,one_third);
mergesort(one_third+1,two_third);
mergesort(two_third+1,high);
merge(low,one_third,two_third);
merge(low,two_third,high);
}//end if
}
at this point I guess I'm done thinking,Any answer/idea would be appreciated.
Here's a partial inspection of your code. I believe there is an issue debugging a 3 way merge sort with 4 values. You should use more values, such as 6 or 7.
Spaces not tabs for StackOverflow
I'll take a guess that the indentation is because you use tab characters in your code and pasted directly. You'll want to expand the tabs in your next post.
Precompiled Headers
Is your project huge? Does it significantly reduce the build time when you change a header or modify the source code?
I find that stdafx usually is more of a hassle and the time spent resolve defects it causes negates any potential savings by having a precompiled header.
Function prototypes should use named parameters
Can you tell the purpose of the different parameters in your declaration of merge and mergeSort?
Ambiguity breeds defects. 'nuff said.
Main function declared wrong.
The main function always returns an int to the operating system, always. The OS can ignore it.
This mechanism is so that script files can execute your program and test for errors.
Readability prevents defects
Invest in spaces around operators. The time saved by sacrificing spaces is negligible. The debugging time saved by having easy to read code is tremendous, especially when having other people review or inspect your code.
Use intermediate variables
Intermediate variables help clarify your program. They don't cost memory when you tell the compiler to optimize. During debugging, they can help show values during calculations.
The typical idiom for reading into a vector is:
int value;
cin >> value;
s.push_back(value);
The at method may have an overflow issue (or at least your not checking for out of bounds issues). The push_back method will cause the vector to expand as necessary.
Meaningful variable names reduces defects
The variable s has no meaning. Something like original_values or number_container are more descriptive. And again, variable name lengths have nothing to do with improving performance. Readable names help reduce the defects injected.
Not checking state of cin
If I enter "Lion" in response to your 2nd prompt, what will be in the 2nd slot of the array?
Don't trust the Users, they aren't perfect.
Don't clear the screen
It may contain useful data, such as the actual numbers entered. So when you are debugging, and want to know what the User actually typed in, it will be lost and gone forever.
Why cin.get twice?
You are asking the User for input without prompting. And twice. Bad Karma between your program and the User.
See cin.ignore if you want to ignore characters until a specific one is received. Something like this perhaps:
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
Magic numbers
In function mergesort, you use the numbers 2 and 3. Why? What's their purpose?
Redundant comments
Most programmers realize that the '/' character in a math expression is division. The comment is redundant.
Also, why divide by 3? It's a nasty number. Do you realize you are performing integer division and your product will be truncated? For example: 1/3 == 2/3 == 0.
USE A DEBUGGER
Lastly, a lot of your program's functionality can be verified easier and quicker by using a debugger. A debugger allows you to execute a statement and see the variable values. You can set breakpoints to stop execution at different places. It's a worthwhile educational investment, start now.
A "classic" 3 way merge sort merges runs 3 at a time, alternating between a source and destination array (or vector or list). The code needs to perform up to 3 compares in order to determine the "smallest" of 3 values from each of the 3 runs, then move the smallest value from it's corresponding run to the destination array. The code also has to handle the case where the end of a run is reached, leaving only 2 runs to merge, then the case where the end of the second run is reached, in which case the rest of the third run is moved to the destination array.
For a ram based sort, I'm not sure this is any faster than a normal 2 way merge. For an external sort, with multiple devices or very large read and writes, then a k way merge with k up to 12 or 16 will be faster.

A function that converts base 10 to binary using stacks to solve it

So I'm asked to write this function in C++ that converts a base 10 integer and prints the integer's binary equivalent
I should use a stack to solve the problem also I'm not allowed to use recursion in my function.
Here's what i think:
While doing the conversion i should start pushing the 1s and 0s into a stack accordingly , the order will be reversed (i think) so i will have to move them to another stack to have the right order after doing that i can start taking the top of the copied stack and print it then pop it to get the next number since the function is not a member function and i cant access the members randomly .
I need to know if my method is right and I'm not exactly sure how to do the conversion.
Here you go:-
#include<iostream>
#include<stack>
using namespace std;
int main()
{
int number;
cin>>number;
stack<int> binary;
while(number>1)
{
binary.push(number%2);
number /= 2;
}
cout<<1;
while(!binary.empty())
{
cout<<binary.top();
binary.pop();
}
return 0;
}
Tip:
Whatever recursion can do, loops can also do.
If you have an idea, always try to implement it first. You can still ask questions if you fail.

recursive divison of number

I have following code to divide one number recursively by another number:
#include <iostream>
using namespace std;
int divide(int number,int dividend){
int answer=0;
if (number>dividend || number==dividend ){
answer+=1;
return divide(number-dividend,dividend);
}
return answer;
}
int main(){
cout<<divide(20,5)<<endl;
return 0;
}
but unfortunately I get zero as answer. Do you see what is wrong?
Answer is a local variable. When you run this code, the first call to divide creates an instance of the answer variable, sets it to 0, and then increments it to 1. Then, when you recursively call divide again, it creates a brand new instance of the answer variable, sets that instance to 0, and then increments that instance to 1.
In your final call to divide, it creates a brand new instance of the answer variable, sets that instance to 0, but since now number<=dividend it doesn't increment it, and it returns that instance of answer which is 0.
In the if branch you are incrementing answer but returning something unrelated (the result of the recursive call). I am sure, this is not what you want. Go from there.
You are recursively running the following code:
if (number>dividend || number==dividend ){
answer+=1;
return divide(number-dividend,dividend);
}
But once the recursive calling ends (which is number < dividend), you will ignore the if statement and return 0;
You do int answer=0; in the start of function call, so when the if statement is wrong, it returns 0 so you should define it as input parameter (by reference call) or make it global (not recommended) and do not set it to zero, just set it before your recursive function call.