I've been doing a recursive function for exercise and there's a part which really confuses me. Here's what the entire code looks like:
void RekFunkcija(int * pok, int max)
{
if (max != 0)
{
cout << pok[max - 1] << endl;
RekFunkcija(pok + 1, max - 1);
}
}
void main()
{
const int max = 5;
int niz[] = { max, 63, max, 126, 252 };
RekFunkcija(niz, max);
}
So the output here is:
What's been confusing me is this part of the recursive function: cout << pok[max - 1] << endl;
I don't understand why does it output always the last member of the array(252)? While the index number(max-1) is decrementing by 1? Shouldn't the output be: 252,126,5,63,5? Does it have anything to do with the pok+1 argument?
Thank you in advance.
The real problem is the use of pok+1 and max-1 together in the function.
That is after the first iteration when 252 is printed, the situation is:
pok on incrementing becomes [63,4,126,252] and max becomes 4.
Now pok[max-1] again gives 4.
So if you want all the array elements to be printed replace pok+1 in the function call RekFunkcija(pok + 1, max - 1); to RekFunkcija(pok, max - 1);
The recursive function shrinks the array (pointer increment on pok + 1) each turn and corrects the max argument. This is what happens in pseudo-ish code:
RekFunkcija([5, 63, 5, 126, 252], 5)
RekFunkcija([63, 5, 126, 252], 4)
RekFunkcija([5, 126, 252], 3)
RekFunkcija([126, 252], 2)
RekFunkcija([252], 1)
RekFunkcija(pok + 1, max - 1);
you have got a problem in this recursive call. each call decreases max by 1 and that makes you print the max - (number of recursive calls) element, but you are also moving pok 1 element ahead, so you are printing the 5th element from the start, and then the 4th from the 2nd place, and so on.
Replace with: RekFunkcija(pok, max - 1);
Additionally, I would recommend using int main() instead of void main, as said here
Related
I'm currently doing a problem that's similar to the maximum contiguous sub-array problem. However, instead of finding just one contiguous sub-array, I can find up to two non-overlapping contiguous subarrays.
For instance for the test case below, the answer is 20 since we can take everything but -20.
5 3 -20 4 8
To do this, I implemented the following code:
long long n, nums[500500], dp[500500][2][3];
long long best(int numsLeft, int beenTaking, int arrLeft) {
if (arrLeft < 0 || numsLeft < 0) return 0;
if (dp[numsLeft][beenTaking][arrLeft] != -1)
return dp[numsLeft][beenTaking][arrLeft];
if (beenTaking) {
// continue Taking
long long c1 = best(numsLeft - 1, beenTaking, arrLeft) + nums[numsLeft];
// stop Taking
long long c2 = best(numsLeft - 1, 0, arrLeft);
return dp[numsLeft][beenTaking][arrLeft] = max(c1, c2);
} else {
// continue not Taking
long long c1 = best(numsLeft - 1, beenTaking, arrLeft);
// start Taking
long long c2 = best(numsLeft - 1, 1, arrLeft - 1) + nums[numsLeft];
return dp[numsLeft][beenTaking][arrLeft] = max(c1,c2);
}
}
This is the function call:
cout << best(n - 1, 0, 2) << endl;
The dp array has been -1 filled before the function call. The nums array contain n elements and is zero-indexed.
Ideone.com link is this: http://ideone.com/P5PB7h
While my code does work for the sample test-case shown above, it fails for some other test-cases (that are not available to me). Are there any edge cases that are not being caught by my code? Where am I going wrong? Thank you for the help.
I tried coming up with a few such edge cases, but am unable to do so.
The problem seems to be on the following lines:
if (beenTaking) {
// continue Taking
long long c1 = best(numsLeft - 1, beenTaking, arrLeft) + nums[numsLeft];
...
} else {
...
}
Adding best(numsLeft - 1, 1, arrLeft) without decrementing arrLeft implies that the "best" results from the first numsLeft - 1 values in nums[] happens at the end of nums[] (at index numsLeft - 1). This may not be true.
The code will therefore likely fail when there are more than 2 positive ranges separated by negative values.
Also, the dp array should be initialized to something clearly out of range, like LLONG_MIN, rather than -1, which could be a legitimate sum.
#include<iostream>
using namespace std;
int BSearch(int array[],int key,int left,int right)
{
if(array[left+right/2]==key)
cout<<left+right/2;
else if(array[left+right/2]<key)
BSearch(array,key,left,right/2-1);
else
BSearch(array,key,right/2,right);
}
int main()
{
int list[]={1,2,3,4,5,6,7,8,9,11,15,21};
BSearch(list,5,0,sizeof(list)/sizeof(int)-1);
}
I wrote this program to perform binary search. I am getting Segmentation fault every time I run it.
Check here:
if(array[left+right/2]==key)
and focus on this left+right/2. Here, the precedence of the operators comes into play. You probably meant add left and right and then divide the sum by two.
However, it will first divide right by two and then add that to left.
So change:
left+right/2
to:
(left+right)/2
everywhere you need to.
Moreover, your logic is flawed. I have already wrote an example in Binary Search (C++), but even Wikipedia can help here. The code of yours works with this:
#include <iostream>
using namespace std;
void BSearch(int array[], int key, int left, int right) {
if (array[(left + right) / 2] == key) {
cout << "found at position " << (left + right) / 2;
return;
} else if (array[(left + right) / 2] > key) {
BSearch(array, key, left, (left + right)/ 2 - 1);
} else {
BSearch(array, key, (left + right)/ 2 + 1, right);
}
}
int main() {
int list[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 15, 21};
BSearch(list, 5, 0, sizeof(list) / sizeof(int) - 1);
}
Output:
found at position 4
Actually the correct way of doing this is not
(left+right)/2
but
left + (right - left)/2
The difference is when working with large lists, the first variant has an overflow problem (undefined behavior with signed ints, not working as expected with unsigned).
Lets illustrate on the char type with range 0..255 unsigned and -128..127 signed (int just has a wider range but the problem remains).
Suppose you want to find a middle of signed chars 40 and 100:
The result of the first expression [(left+right)/2] is: (40+100)/2 = (-116)/2 = -58 (technically undefined, 40+100 char would only be -116 with the standard two's complement implementation but that is not mandated by the C/C++ standard)
The result of the second [left + (right - left)/2] is 40 + (100-40)/2 = 40 + (60)/2 = 40 + 30 = 70
With unsigned char 100 and 250:
The first: (100 + 250)/2 = (94)/2 = 47
The second: 100 + (250 - 100)/2 = 100 + 150 / 2 = 175
For the recursive calls, you need to supply ranges along the "middle" point (again L + (R-L)/2 instead of R/2).
In particular, as also mentioned in the Wikipedia article:
Although the basic idea of binary search is comparatively
straightforward, the details can be surprisingly tricky… (Donald Knuth)
You must be change less than to greater than in second if statement: else if(array[(left+right)/2]>key) because you search reverse side.
And you must change right/2 to (left+right)/2 in third if statement because left may not 0 and right/2 will not corret. You must search from midle to riht side. Solution is
#include <iostream>
using namespace std;
int BSearch(int array[],int key,int left,int right)
{
if(array[(left+right)/2]==key)
cout<<(left+right)/2 << endl;
else if(array[(left+right)/2]>key)
BSearch(array,key,left,(left+right)/2-1);
else
BSearch(array,key,(left+right)/2+1,right);
}
int main()
{
int list[]={1,2,3,4,5,6,7,8,9,11,15,21};
BSearch(list,5,0,sizeof(list)/sizeof(int)-1);
}
The parenthesis issue discussed in the other answers is certainly a big issue, and must be fixed. However, I don't think that is causing the segfault.
The first time BSearch() is called, left and right are 0 and 11, respectively. 5 is the (mistakenly) computed index, pointing to the value of 6. As a result, the last line of BSearch() is called, passing 5 and 11 for left and right.
Following through the function again, the last line is called again, passing 5 and 11 again, ad infinitum.
You must correct how BSearch() computes the indexes to pass to itself.
hello i have this piece of code that i coded based on some other recursion and factorial programs
but my problem is that i am really confused as to how it stored the value and kept it and then returned it at the end
int factorialfinder(int x)
{
if (x == 1)
{
return 1;
}else
{
return x*factorialfinder(x-1);
}
}
int main()
{
cout << factorialfinder(5) << endl;
}
so 5 goes in, and gets multiplied by 4 by calling its function again and again and again, then it gets to one and it returns the factorial answer
why? i have no idea how it got stored, why is return 1 returning the actual answer, what is it really doing?
Source: Image is taken from: IBM Developers website
Just take a look at the picture above, you will understand it better. The number never gets stored, but gets called recursively to calculate the output.
So when you call the fact(4) the current stack is used to store every parameter as the recursive calls occur down to factorialfinder(1). So the calculation goes like this: 5*4*3*2*1.
int factorialfinder(int x)
{
if (x == 1) // HERE 5 is not equal to 1 so goes to else
{
return 1;
}else
{
return x*factorialfinder(x-1); // returns 5*4*3*2*1 when x==1 it returns 1
}
}
Hope this helps.
Return 1 is not returning the actual answer. It's just returning the answer to calling
factorialfinder(1);
which happens in your code.
In any program, a call stack is a space in memory that is used to keep track of function calls. Space from this memory is used to store the arguments to a function, as well as the return value of that function. Whenever some function A calls another function B, A gets the return value of B from that space.
A recursive function is nothing special, it's just an ordinary function calling another function (that happens to be itself). So really, when a recursive function F calls itself, it's calling another function: F calls F', which calls F'', which calls F''', etc. It's just that F, F'', F''' etc. execute the same code, just with different inputs.
The expression if (x == 1) is there to check when this process should be stopped.
The return value of F''' is used by F''. The return value of F'' is used by F'. The return value of F' is used by F.
In Factorial of some number, the operation is (n) * (n-1) * (n-2) * .... * (1).
I've highlighted the 1; this is the condition that's being checked.
A recursive function breaks a big problem down into smaller cases.
Going over your program:
call factorialfinder with 5, result is stored as 5 * factorialfinder(4)
call factorialfinder with 4, result is stored as 5 * 4 * factorialfinder(3)
call factorialfinder with 3, result is stored as 5 * 4 * 3 * factorialfinder(2)
call factorialfinder with 2, result is stored as 5 * 4 * 3 * 2 * factorialfinder(1)
call factorialfinder with 1, result is stored as 5 * 4 * 3 * 2 * 1
in essence it combines the result of a stack of calls to factorialfinder until you hit your base case, in this case x = 1.
Well, the factorial function can be written using recursion or not, but the main consideration in the recursion is that this one uses the system stack, so, each call to the function is a item in the system stack, like this (read from the bottom to the top):
Other consideration in the recursion function is that this one has two main code piece:
The base case
The recursion case
In the base case, the recursive function returns the element that bounds the algorithm, and that stop the recursion. In the factorial this element is 1, because mathematically the factorial of number one is 1 by definition. For other numbers you don't know the factorial, because of that, you have to compute by using the formula, and one implementation of it is using recursion, so the recursive case.
Example:
The factorial of 5, the procedure is: 5*4*3*2*1 = 120, note you have to multiply each number from the top value until number 1, in other words, until the base case takes place which is the case that you already knew.
#include<iostream>
using namespace std;
int factorial(int n);
int main()
{
int n;
cout << "Enter a positive integer: ";
cin >> n;
cout << "Factorial of " << n << " = " << factorial(n);
return 0;
}
int factorial(int n)
{
if(n > 1)
return n * factorial(n - 1);
else
return 1;
}
I am new to C++ programming and I am a bit lost. Here is what I am suppose to do and my code. Any ideas on what to do?
Write a program that uses while loops to calculate the first n Fibonacci numbers. Recall from math the following definition of the Fibonacci sequence:
The Fibonacci numbers Fn are defined as follows. F0 is 1, F1 is 1 and Fi+2 = Fi + Fi+1 for i = 0, 1, 2, ... . In other words, each number is the sum of the previous two numbers. The first few Fibonacci numbers are 1, 1, 2, 3, 5, 8, and 13.
The program should prompt the user for n (the number of Fibonacci numbers) and print the result to the screen. If the user enters an invalid value for n (n <= 0), print an error message and ask the user to re-enter n (an input validation loop for n). This MUST be a loop, not an if statement like Lab 2.
The output should be similar to the following:
Enter the number of Fibonacci numbers to compute: 3
The first 3 Fibonacci numbers are:
1 1 2
#include <iostream>
using namespace std;
int main()
{
int f0 = 0, f1 = 1,f2= 2, i = 0, n;
cout << "Enter the number of Fibonacci numbers to compute: ";
cin >> n;
if ( n <= 0)
{
cout <<"Error: Enter a positive number: ";
return 1;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
cout << "The first " << n << " Fibonacci numbers are: " << endl;
cin >> n;
return 0;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
See this loop, this is where the problem is, since this is homework, i'll not tell exactly what the problem is, take a pen and paper, and start executing your statements, specially this loop, you'll find your error. Just a hint, Fibonacci number is the sum of previous two fibonacci numbers.
You got the f2=f0+f1 right. However, you should note that when you increment i, then f2 becomes f1 and f1 becomes f0.
If you name them like this, it would make more sense:
int f_i_minus_2 = 0, f_i_minus_1 = 1, f_i;
and you would have
f_i = f_i_minus_1+f_i_minus_2;
Now, imagine i is 3. You have written:
f[3] = f[2]+f[1]
When you increment i, you must have:
f[4] = f[3]+f[2]
That is f_i is put in the place of f_i_minus_1 and f_i_minus_1 is put in the place of f_i_minus_2.
(Look at this:
f[3] = f[2] + f[1]
| |
\_____ \____
\ \
f[4] = f[3] + f[2]
)
So you need two assignments after computing f_i:
f_i_minus_2 = f_i_minus_1;
f_i_minus_1 = f_i;
Note that I first changed f_i_minus_2 to f_i_minus_1 because the second assignment destroys the value of f_i_minus_1.
According to wikipedia, your definition is off. F0=0, F1=1, F2=1, F3=2, ...
http://en.wikipedia.org/wiki/Fibonacci_number
Assuming wikipedia is right your loop is basically
int i = 0, f, fprev;
while( i < n )
{
if( i == 0 )
{
f = 0;
fprev = 0;
}
else if( i == 1 )
{
f = 1;
}
else
{
int fnew = f + fprev;
fprev = f;
f = fnew;
}
i++;
}
As others have pointed out, since you never modify f0 and f1 in the
loop, f2 isn't going to depend on the number of times through the
loop. Since you have to output all of the numbers at the end anyway,
why not try keeping them in an array. I'd initialize the first two
values manually, then loop until I had enough values.
(This can be done quite nicely using the STL:
// After having read n...
std::vector<int> results( 2, 1 );
while ( results.size() < n )
results.push_back( *(results.end() - 1) + *(results.end() - 2));
I'm not sure that this is what your instructor is looking for, however.
I rather suspect that he wants you to to some indexing yourself. Just
remember that if you initialize the first two values manually, your
index must start at 2, not at 0.)
Another thing: the specification you post says that you should loop if
the user enters an illegal value. This is actually a little tricky: if
the user enters something that isn't an int (say "abc"), then 1)
std::cin will remain in error state (and all further input will fail)
until cleared (by calling std::cin.clear()), and the illegal
characters will not be extracted from the stream, so your next attempt
will fail until you remove them. (I'd suggest >>ing into an
std::string for this; that will remove everything until the next white
space.) And don't ever access the variable you >>ed into until
you've checked the stream for failure—if the input fails. If the
input fails, the variable being input is not modified. If, as here, you
haven't initialized it, then anything can happen.
Finally (and I'm sure this goes beyond your assignment), you really do
need to do something to check for overflow. Beyond a certain point,
your output will become more or less random; it's better to stop and
output that you're giving up in this case.
If you are interested, there are better ways to calculate it.
Is it possible to print a random number in C++ from a set of numbers with ONE SINGLE statement?
Let's say the set is {2, 5, 22, 55, 332}
I looked up rand() but I doubt it's possible to do in a single statement.
int numbers[] = { 2, 5, 22, 55, 332 };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
Pointlessly turning things into a single expression is practically what the ternary operator was invented for (I'm having none of litb's compound-statement trickery):
std::cout << ((rand()%5==0) ? 2 :
(rand()%4==0) ? 5 :
(rand()%3==0) ? 22 :
(rand()%2==0) ? 55 :
332
) << std::endl;
Please don't rat on me to my code reviewer.
Ah, here we go, a proper uniform distribution (assuming rand() is uniform on its range) in what you could maybe call a "single statement", at a stretch.
It's an iteration-statement, but then so is a for loop with a great big block containing multiple statements. The syntax doesn't distinguish. This actually contains two statements: the whole thing is a statement, and the whole thing excluding the for(...) part is a statement. So probably "a single statement" means a single expression-statement, which this isn't. But anyway:
// weasel #1: #define for brevity. If that's against the rules,
// it can be copy and pasted 7 times below.
#define CHUNK ((((unsigned int)RAND_MAX) + 1) / 5)
// weasel #2: for loop lets me define and use a variable in C++ (not C89)
for (unsigned int n = 5*CHUNK; n >= 5*CHUNK;)
// weasel #3: sequence point in the ternary operator
((n = rand()) < CHUNK) ? std::cout << 2 << "\n" :
(n < 2*CHUNK) ? std::cout << 5 << "\n" :
(n < 3*CHUNK) ? std::cout << 22 << "\n" :
(n < 4*CHUNK) ? std::cout << 55 << "\n" :
(n < 5*CHUNK) ? std::cout << 332 << "\n" :
(void)0;
// weasel #4: retry if we get one of the few biggest values
// that stop us distributing values evenly between 5 options.
If this is going to be the only code in the entire program, and you don't want it to return the same value every time, then you need to call srand(). Fortunately this can be fitted in. Change the first line to:
for (unsigned int n = (srand((time(0) % UINT_MAX)), 5*CHUNK); n >= 5*CHUNK;)
Now, let us never speak of this day again.
Say these numbers are in a set of size 5, all you gotta do is find a random value multiplied by 5 (to make it equi probable). Assume the rand() method returns you a random value between range 0 to 1. Multiply the same by 5 and cast it to integer you will get equiprobable values between 0 and 4. Use that to fetch from the index.
I dont know the syntax in C++. But this is how it should look
my_rand_val = my_set[(int)(rand()*arr_size)]
Here I assume rand() is a method that returns a value between 0 and 1.
Yes, it is possible. Not very intuitive but you asked for it:
#include <time.h>
#include <stdlib.h>
#include <iostream>
int main()
{
srand(time(0));
int randomNumber = ((int[]) {2, 5, 22, 55, 332})[rand() % 5];
std::cout << randomNumber << std::endl;
return 0;
}
Your "single statement" criteria is very vague. Do you mean one machine instruction, one stdlib call?
If you mean one machine instruction, the answer is no, without special hardware.
If you mean one function call, then of course it is possible. You could write a simple function to do what you want:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int setSize = 5;
int set[] = {2, 5, 22, 55, 332 };
srand( time(0) );
int number = rand() % setSize;
printf("%d %d", number, set[number]);
return 0;
}