Does stack come into the frame in the following code? If num=5. Why am i getting the output as zero..what about the numbers from 5 to 1?
void rec(int num)
{
cout << num << endl;
if( num > 0 )
return rec(num-1);
cout << "after" << num << endl;
}
does it include the concept of stack?
"Why am i getting the output as zero"
Look at the logic of you function. if(num>0) - return rec(num-1);.
So for every nubmer above 0, the function will just call itself again with num-1.
And only when num==0 you will get to this line
cout<<"after"<<num<<endl;
Meaning that for every number you will enter, the function will do nothing and call itself again with number-1 before the cout<<"after"<<num<<endl; line, and at the last time it will not call it self again (since num > 0 condition is false) and it will print 0.
If you want to see the "returned value", you could do something like this:
void rec(int num)
{
cout << num << endl;
if( num > 0 )
rec(num-1);
cout << "after" << num << endl;
}
The return rec(num-1); is technically valid, but since the function doesn't actually return soemthing, it's the same as writing:
if (num > 0)
{
rec(num-1);
return;
}
Related
I was writing the code for the problem. Median of the stream of integers when I encountered an issue. Note that this issue is not the algorithmic but rather ambiguous behavior of the priority_queue size.
#include <bits/stdc++.h>
using namespace std;
priority_queue<double> small;
priority_queue<double, vector<double>, greater<double> > large;
void rebalance()
{
cout << "Initial size\n";
cout << "small " << small.size() << " large " << large.size() << endl;
if (small.size() - large.size()>1)
{
large.push(small.top());
small.pop();
}
else if (large.size() - small.size()>1)
{
cout << "Unexpectedly goes here\n";
cout << "garbage size difference " << large.size() - small.size() << endl;
small.push(large.top());
large.pop();
}
}
void addNum(int num) {
if (small.size() == 0 || num<small.top())
{
small.push(num);
}
else
{
large.push(num);
}
rebalance();
}
double findMedian() {
if (small.size() == large.size())
{
double ans = (small.top() + large.top()) / 2.0;
return ans;
}
else if (small.size()>large.size())
{
return (double)small.top();
}
else
{
return (double)large.top();
}
}
int main()
{
std::ios_base::sync_with_stdio(false);
int num = 5;
addNum(num);
cout << findMedian() << endl;
return 0;
}
The output for this code is
Initial size
small 1 large 0
Unexpectedly goes here
garbage size difference 18446744073709551615
fish: “./a.out” terminated by signal SIGSEGV (Address boundary error)
In the rebalance function the initial size of small is 1 and large is 0 which suggest that the loop should neither enter the if condition nor the else if condition but the loop enters the else if condition with a garbage value in size.why does this happen? Moreover I tried saving the small and large size in an integer variable and then comparing them in conditionals,which lead to acceptance of the code. Hence the algorithm handles the correctness.
What leads to this garbage value?
In
else if(large.size()-small.size()>1)
size() returns an unsigned number. A unsigned number can never be negative so if would be a negative number it wraps around to the largest number it could be and then goes backwards from there. Since large has a size of 0 and small has a size of 1 then 0 - 1 gives you 18446744073709551615. I believe what you are trying to do should be expressed as
if(small.size() < large.size())
{
small.push(large.top());
large.pop():
}
else if(large.size() < small.size())
{
large.push(small.top());
small.pop();
}
I'm having a little trouble with my code. It's pretty much supposed to open two files, and compare the first twenty line of the file "StudentAnswers.txt" [inputted as a char into a char array] against a char value in (each line of another file) "CorrectAnswers.txt" in another array at the same position (index). It's like a linear search, but the same position in the arrays. Then a report should be displayed, detailing which question the student missed, the given answer, the correct answer, and if the student passed (got >= 70%) or not, like the following:
Report for Student X:
2 (A/D), 3 (C/D), 5(D/A)
This student passed the exam!
Then it should clear the SAArray, and feed the next twenty lines from StudentAnswers.txt, and start the process all over again. I guess the program has to determine the number of students from (lines of 'StudentAnswers.txt' file / 20).
I'm having trouble displaying the report, and having the array clear itself after the program. I'm guessing this can be done with a while loop and an accumulator for the number of students (to be determined by above equation).
Also, Visual Studio seems to go to "Missed __ questions for a total of ___ %", and then keep looping -858993460.
Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
{
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
{
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
{
CA >> CAArray[a];
a++;
} // while loop to feed char into the array
while (b < 20)
{
SA >> SAArray[b];
b++;
}
} // while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
}
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
{
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
{
if ((CAArray[counter]) == (SAArray[counter]))
{
correct++;
cout << "Good job!" << endl;
} // correct handling
else
{
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
} // incorrect handling
counter++;
} // while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
{
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
{
if(1=1)
{
catcher_size
}
else
{
cout << "";
starter++;
}
}
}
else if (PassFail(percent) == "fail")
{
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
{
if ((catcher[starter]) == -858993460)
{
starter++;
}
else
{
cout << "";
starter++;
}
}
}
return;
}
string PassFail(float percent)
{
if (percent >= 0.70) // if <pass>
{
return "pass";
}
else // if <fail>
{
return "fail";
}
cout << endl;
}
To get a loop you should keep streams open instead of closing them after reading 20 lines.
As pseudo code that would be:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
}
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
You would also need to pass correct, incorrect, counter by reference so that the GradeReturn can change their value and their by do the accumulation.
Like:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
Further you shouldn't rely on being able to read exactly Nx20 lines from the files every time. A file could have, e.g. 108 (5x20 + 8) lines, so you code should be able to handle the with only 8 lines. In other words, don't hard code 20 in your function like while (counter < 20). Instead pass the number of lines to be handled and do while (counter < number_to_handle).
Something like this as pseudo code:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
}
}
if (a != 0)
{
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
One problem you have is you're trying to compare C-style strings with the == operator. This will compare them essentially as if they were pointers to char, i.e. compare whether they point at the same location in memory, not compare the contents of the string. I urge you to look up array-decay and c-string variables to understand more.
Specifically, if (PassFail(percent) == "pass") isn't going to do what you want it to. strcomp doc, strncmp doc using std::string variables instead of c-style strings would all work, but it would be better simply to compare percent to a value, i.e. if(percent >= 0.70 directly instead of calling PassFail and comparing a string.
There are many other issues here also, you at one point call PassFail but do nothing with the return value. The only side affect of PassFail is cout << endl, if that's what you intend, it's a poor decision and hard to read way to put a newline on the console.
Try asking your compiler for more warnings, that's often helpful in finding these types of issues. -Wall -Wextra work for gcc, you may have to read your compiler manual...
int bounce(int n) {
if (n == 0)
{
cout << "0" << endl;
}
if (n > 0)
{
cout << n << endl;
bounce(n - 1);
cout << n << endl;
}
}
int main()
{
int x;
cout << "Choose a number: ";
cin >> x;
cout << bounce(x) << endl;
system("pause");
return 0;
}
I recently started for my first time with C++ (2 hours ago or so :D ) and the problem i have is "Bounce: not all control paths return a value", I don't know how to fix this, obviously i need return 0; or something somewhere in the function but i can't find out where without ruining how it works.
Example : bounce(5) ==> prints out 5 4 3 2 1 0 1 2 3 4 5
TL DR: Where to place the return in bounce to make it work correctly.
Actually none of your control paths returns a value. As you only use the function to print something on the screen, it does not have to return anything. Just make the return type void:
void bounce(int n) {
/*...*/
}
And then dont cout the result of the function call (once you make it void the function wont return anything anyhow), i.e. instead of:
std::cout << bounce(x) << std::endl;
simply write
bounce(x);
You already print on the screen inside the function.
When you define a function in C++, you specify the return type before the function name.
Your int bounce() function is declared as returning an integer but it does not return any values at all. Therefore, that causes an error.
You can declare your function using void bounce(), which tells the compiler that your function will not return any values. That will eliminate the error.
Note: Although you use cout to display your values, this is different from returning a value in the way we are talking about. Returns values are specified using the return keyword.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
We have to write a gcd calculator, iteratively and recursively, and we are given a test script and my program fails 2/10 tests(gcd_iterative(1000, 48) = 1000, gcd_iterative(48, 24) = 48). so I showered my program with print statements 'and it worked. I started removing 1 statement at a time and there is 1 line where if I remove the statement it produces the wrong answer. Why does this happen and how can I fix it?
using namespace std;
#include <sstream>
#include <string>
#include <iostream>
#include <cstdlib>
int gcd_iterative(int m, int n)
{
int r;
while(r != 0)
{
r = m % n;
m = n;
n = r;
}
return m;
}
int gcd_recursive(int m, int n)
{
if(n == 0)
{
return m;
}
else
{
return gcd_recursive(n, m % n);
}
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
cerr << "Usage: " << argv[0] << " <integer m> <integer n>" << endl;
return 1;
}
istringstream iss;
iss.str(argv[1]);
int m;
if (!(iss >> m))
{
cerr << "Error: The first argument is not a valid integer." << endl;
return 1;
}
iss.clear();
iss.str(argv[2]);
int n;
if (!(iss >> n))
{
cerr << "Error: The second argument is not a valid integer." << endl;
return 1;
}
cout << "" << endl;
cout << "Iterative: gcd(" << m << ", " << n << ") = " << gcd_iterative(m, n) << endl;
cout << "Recursive: gcd(" << m << ", " << n << ") = " << gcd_recursive(m, n) << endl;
return 0;
}
the print statement is cout << "" << endl;.
The problem is in here:
int r;
while(r != 0)
{
r = m % n;
m = n;
n = r;
}
return m;
The value of r is not initialized to anything, so if the initial value is zero, the algorithm will terminate on the while loop and just return the value of m unchanged.
C++ is not required to initialize the values of stack variables to any default value or anything else, so the value in the r variable is whatever was left on the stack by the previous function call. It would seem that it just so happens that cout << endl; leaves a nonzero value in the correct stack position for r to have a nonzero value, and actually run the algorithm. (Note that if C++ did supply a default value, the default value would presumably be zero anyway, so you would still be forced to initialize).
In general, you should initialize the default values of stack variables to a safe value, rather than relying on their default values. So in this case, the fix is to set r to any nonzero value when you first declare it. E.g. int r = 1;
Side note: In C/C++ any integer value can be used as a boolean, and zero is false, so your while condition can be simplified to just while(r) rather than while(r != 0); these are completely equivalent expressions as far as the while loop is concerned.
when program's result changes like this, it is likely you forgot to initalize some variable. In your case, it looks you forgot to initialize r:
int r;
while(r != 0)
'r' will get an arbitrary value (whatever happens to be in the CPU register). It is likely that without print statements, r is zero and thus the while() loop never runs. You want to set to non-zero value explicitly.
I'm trying to design a program that takes an integer array as input, and then returns all combinations of values that add up to a predetermined sum. For the sake of clarity, my recursive function will return true when the total adds up to 10.
However, I also want it to return the values from the array that comprise of this total, so my definition is as follows;
If suminarray returns true, print each number from the array.
My hope was, once my base clause is reached, the recursion would unwind, and my if statements would all be evaluated, and each value would be printed from my if statement. However, all that is printed is last value from the array which made up the target total, not all the values that preceded it.
I've likely misunderstood the recursive behaviour of C++. I know how to work with recursive return calls, but logically, if the if statement can't be evaluated until the recursive function returns true or false, shouldn't they unwind, also?
#include <iostream>
bool suminarray(int *numbers, const int &size, int startPos, int total);
using namespace std;
int main()
{
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int startPos = 0;
int total = 0;
suminarray(numbers, 10, 0, total);
return 0;
}
bool suminarray(int *numbers, const int &size, int startPos, int total)
{
if(total == 10)
{
cout << "result. " << endl;
return true;
}
else if(total > 10)
{
return false;
}
else
{
for(int i = startPos; i < size; i++)
{
cout << " loop " << i << endl;
cout << " total" << total << endl;
if(suminarray(numbers, size, i+1, total+numbers[i]) == true)
{
cout << "Uses " << numbers[i] << endl;
}
}
}
}
Edit: correction to source code.
The immediate problem (which your compiler should be warning you about), is that you have no return statement in the final else block, which causes the function to fall off the end without returning either true or false, leading to undefined behavior. If you fix that in the most obvious way:
else
{
for(int i = startPos; i < size; i++)
{
cout << " loop " << i << endl;
cout << " total" << total << endl;
if(suminarray(numbers, size, i, total+numbers[i]) == true)
{
cout << "Uses " << numbers[i] << endl;
return true;
}
}
return false;
}
your program then works, but it only prints the FIRST set of values that add up to 10 that it finds.
That immediately shows you the problem with your approach -- each function call can only return ONCE -- you can't (easily) have it both return success AND continue to try more alternatives.
As you've already guessed, the way you're imagining the recursive function unwinding is wrong.
In your example, you want to get to a total of 10, with numbers starting at 1, and ending at 9. So, first your recursive function will make the total = 1. Then it will add another 1 to that until it gets all the way down to the tenth 1. Then it will print result, then it will unwind 1 step, and print 1.
Good so far right? Well, here's where it goes off track. At this point it doesn't unwind all the way. It still stays at 9, but this time it adds a 2 to that, fails goes back until it unwinds to a sum of 8. Now it tries 2 and works this time! Printing result, then 2.
This, as i've understood, isn't what you want. What you should be doing is make something else to hold your array of answers, and not just print them.
I know how to work with recursive return calls, but logically, if the if statement can't be evaluated until the recursive function returns true or false, shouldn't they unwind, also?
This is correct. The reason you are only seeing one print statement at the end is because only one call is returning 'true'. Therefore the 'if' statement is only true once and you only see one print statement for "Uses ".
I believe your mistake is that you didn't add a return statement after your for loop. This means the return value for your function is actually undefined. Start using the -Wall flag when you compile to make sure you don't make this mistake. Here is a version where I added a "return true;" after the 'for' loop:
#include <iostream>
bool suminarray(int *numbers, const int &size, int startPos, int total);
using namespace std;
int main()
{
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int startPos = 0;
int total = 0;
suminarray(numbers, 10, startPos, total);
return 0;
}
bool suminarray(int *numbers, const int &size, int startPos, int total)
{
if(total == 10)
{
cout << "result. " << endl;
return true;
}
else if(total > 10)
{
return false;
}
else
{
for(int i = startPos; i < size; i++)
{
cout << " loop " << i << endl;
cout << " total" << total << endl;
if(suminarray(numbers, size, i, total+numbers[i]) == true)
{
cout << "Uses " << numbers[i] << endl;
}
}
}
return true;
}