Vector error,a very confusing segmentation error? - c++

So basically,I am doing a code which searches for an element of a vector inside a vector.While I thought of the approach , implementing it got me a segmentation error. I narrowed down the problem
In the code if I decomment the line in the for loop while commenting the above then all elements of B[i] are being displayed.Why then is a segmentation error being thrown. I think the binary_return is more or less correct and if I replace the line with
binary_return(A,0,A.size(),B[1])
then its working.
Here is the code:
#include<iostream>
#include<vector>
using namespace std;
int binary_return(vector<int> a,int start,int end,int seek)
{
int mid = (start+end)/2;
//cout<<start<<" "<<seek<<" "<<mid;
if(end!=start)
{
if(a[mid]==seek)
{
return mid;
}
else if(a[mid]>seek)
{
return binary_return(a,start,mid,seek);
}
else if(a[mid]<seek)
{
return binary_return(a,mid,end,seek);
}
}
else
return -1;
}
int main()
{
vector<int> A{1,3,6,9,23};
vector<int> B{1,4,23};
cout<<B[0]<<B[1]<<B[2];
for(int i=0;i<B.size();i++)
{
cout<<binary_return(A,0,A.size(),B[i]);
//cout<<binary_return(A,0,A.size(),B[0]);
}
return 1;
}

Your code is not handling the last case correctly and ends up in infinite recursion.
This unfortunately in C++ means that anything can happen (you're not guaranteed to get a meaningful error).
Add a debug print at the beginning of the function and you'll see in which cases you're entering infinite recursion.

You have infinite recursion in third if statment
The correct code if the following:
#include<iostream>
#include<vector>
using namespace std;
int binary_return(vector<int> a,int start,int end,int seek)
{
int mid = (start+end)/2;
//cout<<start<<" "<<seek<<" "<<mid;
if(end!=start)
{
if(a[mid]==seek)
{
return mid;
}
else if(a[mid]>seek)
{
return binary_return(a,start,mid,seek);
}
else if(a[mid]<seek)
{
// In your sample you forgot to add +1 (mid+1) for next start
return binary_return(a,mid+1,end,seek);
}
}
else
return -1;
}
int main()
{
vector<int> A{1,3,6,9,23};
vector<int> B{1,4,23};
for(int i=0;i<B.size();i++)
{
cout<<binary_return(A,0,A.size(),B[i]);
}
return 0;
}

Related

Binary Search Recursion warning

#include <iostream>
using namespace std;
int i = 0;
int binarySearch(int arr[],int left, int right, int item)
{
int midpoint;
bool found{false};
if(left < right && !found)
{
midpoint = left + (right - left)/2;
if(arr[midpoint]<item)
{
binarySearch(arr,midpoint+1,right,item);
}
else if(arr[midpoint]>item)
{
binarySearch(arr,left,midpoint-1,item);
}
else
{
found = true;
return midpoint;
}
}
}
int main()
{
int arr[] = {10,20,30,40};
int x = binarySearch(arr,0,3,40);
cout << x ;
}
How is it returning the correct value of the item searched for although its not even reaching the return statement.
It is reaching the base case when it is only one element in the array, but it should not reach the return statement, thus it should return garbage, but it is returning the correct index every time.
In most cases you don't return any value so you get whatever happens to be in the result register or stack slot at the time. This can work by accident, if you are unlucky.
Turn on compiler warnings and always fix them. Best to turn warnings into errors.

Getting wrong answer in a DP problem although implementation looks correct

I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}

SPOJ: What is the difference between these two answers for KURUK14

I have solved this problem and got AC. My problem is related to equivalence of following two approaches. The first code got accepted, while the second didn't.
As far as I can discern, both are completely equivalent for all the (valid) test cases any human can think of. Am I wrong? If so, what test case can differentiate them?
Code#1 (Accepted one):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
}
bool f = true;
for(int k=0;k<N;k++)
{
f = f && M[k];
}
return f;
}
int main() {
M=new bool[1002];
int num=0;
scanf("%d",&num);
while(num){
int N=0;
scanf("%d",&N);
if(proc(N))
printf("YES\n");
else
printf("NO\n");
num--;
}
return 0;
}
Code #2 (WA):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
else
return false;
}
return true;
}
int main() {
//Exactly same as code#1
}
The bug has nothing to do with the algorithm itself—it's very possible both the algorithms are correct. But the second implementation is wrong.
When you reach a test case which should return NO, you exit the function prematurely. Which means there are some numbers from the current test case left unread in the input, which of course confuses further reading thoroughly. This means the bug only manifests when T > 1.

Input not terminating because of a comment

This cpp code is not terminating. I have tried the code by various inputs but this is not terminating.I think there is a bug in the 52th line, when I comment the 52 line than the code is working fine.
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
// binary search for larger elements
using namespace std;
vector <int > q;
// bsearch value uses hte
#define bvector q // just define these values to use them in your functin
#define VALUE(x) bvector[x]
int b_search(int value){
int low=0,high=bvector.size(),mid;
mid=(low+high)/2;
cout << "In the bsearch";
while(low<high)
{
if(VALUE(mid)==value)
return mid;
else if(VALUE(mid)>value)//
high=mid;
else if(VALUE(mid)<value)
low=mid+1;
}
if(VALUE(low)>value)
return low;
return -1;
}
int main(){
int i;
for(scanf("%d",&i);i;scanf("%d",&i))
q.push_back(i); // this is for taking input in the vectot
sort(q.begin(),q.end());
for(i=0;i<q.size();i++)
printf("%d ",q[i]);// for printing the sorted
int j;
printf("Enter the elements you want to search");
int x;
scanf("%d",&x);
// BUG is present in this lines
cout <<"This is the end of scanf";// if this line is commented then the 54th line is not reached
j=b_search(x);
printf("%d ",j);
return 0;
}
The statement : mid=(low+high)/2; is a bit misplaced. It should be inside the while loop.
This is probably what is causing an infinite loop.

Binary Search with few modification

While I am trying to compile the code with few modification in binary search recursive function. The program is acting weird. Some time it gives the correct value and some time it goes to infinite loop. Please explain what went wrong with the code. I am using DEV C++ as an IDE.
CODE:
#include<iostream>
#include<sstream>
using namespace std;
//function to compare the two integers
int compare(int low, int high)
{
if (low==high)
return 0;
if (low<high)
return 1;
else
return -1;
}
//Function for binary search using recursion
int *BinarySearch(int *Arr,int Val,int start,int end)
{
int localstart=start;
int localend=end;
int mid=(start+end)/3;
cout<<"MID:"<<mid;
int comp= compare(Val,Arr[mid]);
if(comp==0)
return &(Arr[mid]);
else if (comp>0)
return BinarySearch(Arr,Val,localstart,mid-1);
else
return BinarySearch(Arr,Val,mid+1,localend);
return NULL;
}
main()
{
int *arr;
arr= new int [256];
string str;
getline(cin,str);
stringstream ss;
ss<<str;
int index=0;
while(ss>>arr[index])
{index++;}
//cout<<arr[index-1];
cout<<"Enter Value:";
int value;
cin>>value;
int *final;
final=BinarySearch(arr,value,0,index-1);
if(final!=NULL)
cout<<"Final:"<<*final;
else
cout<<"Not Found";
getchar();
getchar();
return 0;
}
Two ideas:
What should BinarySearch do if Val is not in the array? Trace out what your code does in this case.
(start+end)/3 probably isn't the middle of the current range.