#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.
Related
how does line return((count-2)+(count-1)) works in below cpp program?
ans of the given code is -18 .how to know the ans without running the code
and out of two function count(n-2) and count(n-1) which one is called first and how is it decided?
#include <iostream>
using namespace std;
int count(int n);
int main() {
int n, m;
n = 4;
m = count(n);
cout << m;
}
int count(int n)
{
if (n<0)
{
return n;
}
else
{
return (count(n - 2) + count(n - 1));
}
}
There's no sequencing between the left-hand and right-hand side of the + operator. So which one is evaluated first is unknown (and left up to the compiler).
The only way to figure it out is to step thought he code line by line, statement by statement, expression by expression in a debugger.
However, since each recursive call is not depending on any side-effects they can be executed independently of each other, and therefore the order doesn't matter as the result will always be the same.
We can simply draw a binary tree to know the answer without compiling it. Just start breaking branch into two for count(n-1) and count(n-2) then add all leaves of trees.
Like if we took n as 4 it would be split as 3 and 2, Which would be two branch of 4. Similarly and recursively break nodes in to branch. 3 would be split into 1 and 2 so on. till leaves node is less then 0. In the end add value of all leaves to get the answers.
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.
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
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
srand(time(NULL));
int main(){
int botguess;
int playerinput;
int mi=1, ma=100;
int turns = 0;
cout<<" what do you want guessed:";
cin>> playerinput;
cout<< "time for me to start guessing\n";
for(int i = 0;i < 50;i++) {
botguess = rand() % ma + mi;
if(playerinput > botguess){ //<--the problem
mi = botguess;
}
if(playerinput < botguess) {
ma = botguess;
}
cout<<"Max:"<<ma<<"\n"<<botguess<<"\n";
Sleep(1000);
if(botguess == playerinput)
{
cout<<"you win";
}
}
cin.get();
return 0;
}
So I've been tearing my hair out about why logically this doesn't work. This is a program that is supposed to guess the players number quickly but not instantly. The program doesn't perform like it looks.
The line that I noted causes a bug where the max number possible is being ignored. im getting number that are 100+ but under 200 and i don't know why. When I remove the lines concerning the mi variable nested in the statement in the for loop. The program doesn't go over 100 but I don't get the other end of the program solving the player number.
Also if you figure it out can you please explain it to me I don't just want a answer.
botguess = rand() % (ma - mi + 1) + mi
You don't want ma different numbers, you want much less of them. Look at an example: (5..10) contains 6 different numbers: [5, 6, 7, 8, 9, 10]; but if you do rand() % 10 + 5, you're getting numbers from 5 (5 + 0) to 14 (5 + 9). What you need is rand() % 6 + 5, where 6 is 10 - 5 + 1.
The problem you are having is caused by the fact that mi is set to botguess, which can easily be greater than zero, then on the next cycle if ma is still 100 (or anywhere near it), you're going to sometimes get numbers greater than 100 set into botguess.
Edit added: the % operator in C++ is mod division (ie. gives the remainder of integer division) So for example, 98 % 100 + 15 will be 98 + 15, i.e. 113
This link may help you:
http://www.cplusplus.com/reference/cstdlib/rand/
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;
}