Binary search optimisation - c++

I implemented binary search in two ways and wondering which is more efficient? please help me know which is more efficient and how can it further be optimized? is time complexity remains same in both approach? I am a beginner in programming.
approach 1;
#include<iostream>
using namespace std;
bool BinarySearch(int*a,int n,int s ){
if(n==1){
if(a[0]==s)
return true;
else
return false;
}
else{
if(s<a[n/2]){
int U[n/2];
for(int i=0;i<n/2;i++){
U[i]=a[i];
}
return BinarySearch(U,n/2,s);
}
else{
int V[n-n/2];
for(int i=0;i<n-n/2;i++){
V[i]=a[i+n/2];
}
return BinarySearch(V,n-n/2,s);
}
}
}
int main(){
int array[10]={2,4,6,8,10,12,14,16,18,22};
cout<<BinarySearch(array,10,9);
}
approach 2:
#include<iostream>
using namespace std;
bool Bsearch(int arr[],int s,int l,int x){
cout<<"calling bsearch with arguments "<<s<<' '<<l<<' '<<x<<endl;
if(l==1)
return arr[s]==x;
int h=l/2;
if(x<arr[s+h])
return Bsearch(arr,s,h,x);
else
return Bsearch(arr,s+h,l-h,x);
}
int main(){
int marks[11]={17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,11,32);
}
Thanks in advance for the kind help.

Other posters are correct that variable-length arrays are not good C++. If you define your main() as:
int main() {
std::array<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
or:
int main() {
std::vector<int> marks{17,18,20,22,24,26,28,30,32,34,36};
cout<<Bsearch(marks,0,32);
}
then you can drop the pointer/length pair in the parameter list to your binary-search function. The function prototype becomes something like:
bool Bsearch(const std::array<int>& arr, int s, int x);

Related

how can i count digits of a number using recursion?

yes i know other ways to count digits and returning to main function from the recursion function, but i'd like to print it in the void function. im having difficulty with it. could somebody help?
#include <iostream>
using namespace std;
void recursive_function(int num)
{
int sum=0;
while(num!=0){
recursive_function(num/10);
sum++;
}
cout<<sum<<endl;
}
int main()
{
recursive_function(345289467);
return 0;
}
If you do not want to use the return-stack to count your digits, you will need to pass the current count throughout the call stack as function parameter:
void recursive_function(int num, int count=1)
{
if (num>=10) {
recursive_function(num/10, count+1);
} else {
cout<<count<<endl;
}
}
your recursive function should return integer.
#include <iostream>
using namespace std;
int recursive_function(int num)
{
if(num>9){
return 1+recursive_function(num/10);
}else
return 1;
}
int main()
{
cout << recursive_function(123456789);
return 0;
}

how to efficiently appraoch for SPOJ Square free numbers?

I tried my best to solve Spoj problem No Squares numbers but I'm getting (TLE). Please tell how to approach. I'm unable to find any proper approach. Here is my code:
#include <bits/stdc++.h>
using namespace std;
#define size 10000004
int mark[size+1];
void sieve()
{
for(int i=2,k;(k=i*i)<=size;++i)
{
for(int j=k;j<=size;j=j+k)
mark[j]=-1;
}
}
int fn(int a,int b,int c)
{
int i,j,k,cnt=0;
for(i=a;i<=b;++i)
{
j=i;
if(mark[j]!=-1)
{
while(j>0)
{
if(j%10==c)
{
cnt+=1;
break;
}
else
j=j/10;
}
}
}
return cnt;
}
int main()
{
sieve();
int t,a,b,c;
cin>>t;
for(int i=0;i<t;t++)
{
cin>>a>>b>>c;
cout<<fn(a,b,c)<<endl;
}
}

UVA(769) :critical links getting wrong answer

I am solving Critical links problem on UVA.The problem is about finding the bridges in the Graph.I used the same algorithm here.But I am continuously getting wrong answer.
Please suggest what's wrong with my code.
//Bridges in a Graphs
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<utility>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define MAX 205
int parent[MAX],timer=0,low[MAX],disc[MAX];
bool vis[MAX];
vector<pair<int,int> >st;
vector<vector<int> >G(MAX);
bool cmp(const pair<int,int> a,pair<int,int> b)
{
if(a.first==a.second)
return a.second<b.second;
else
return a.first<b.first;
}
void reset()
{
st.clear();
memset(parent,-1,sizeof parent);
memset(vis,false,sizeof vis);
for(int i=0;i<=MAX;i++)
G[i].clear();
}
void dfs(int u)
{
vis[u]=true;
disc[u]=low[u]=timer++;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!vis[v])
{
parent[v]=u;
dfs(v);
low[u]=min(low[u],low[v]);
if(low[v]>low[u])
st.push_back(make_pair(min(u,v),max(u,v)));
}
else if(v!=parent[u])
low[u]=min(low[u],disc[v]);
}
}
int main()
{
int n,t=0;
while(cin>>n)
{
reset();
if(t>0)
cout<<endl;
if(n==0)
{
cout<<"0"<<" critical links\n";break;
}
int node,count;
for(int j=0;j<n;j++)
{
scanf("%d (%d)",&node,&count);
for(int i=0;i<count;i++)
{
int x;
scanf("%d",&x);
G[node].push_back(x);
G[x].push_back(node);
}
}
for(int i=0;i<n;i++)
{
if(!vis[i])
dfs(i);
}
sort(st.begin(),st.end(),cmp);
cout<<st.size()<<" critical links\n";
for(int i=0;i<st.size();i++)
cout<<st[i].first<<" - "<<st[i].second<<endl;
t++;
}
}
Finally I got it,little bit flaw in std::sort cmp function and it is
bool cmp(const pair<int,int> a,pair<int,int> b)
{
if(a.first==b.first)
return a.second<b.second;
else
return a.first<b.first;
}
also in dfs function low[v]>disc[u] instead of low[v]>low[u].

Control reached end of Non Void Function

I am trying to call this recursive method,but I don't understand why it's not reaching the else statement to return mul. I am passing value 0,in the main function,which is less than n,and on x becoming greater than n,it should move to else function.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n,mul=0;
vector <int> a;
int calc(int x)
{ int mul,chk;
int l=n;
if(x<n)
{
chk=a[x]*(l-1);
l--;
if(mul<chk)
{
mul=chk;
}
calc(x+1);
}
else
{ return mul;}
}
int main() {
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a.begin(),a.end());
int z=calc(0);
cout<<z;
return 0;
}
Wihtout knowing the exact error message, I am not 100% sure what is the problem, but I guess it is the following:
Your function looks like this (simplified):
int calc(int x) {
if(someCondition){
if(otherCondition){}
calc(x+1);
} else {
return mul;
}
}
The problem is that if someCondition is true, the function does not return anything. You probably want to do:
return calc(x+1);
instead of just
calc(x+1);

Segmentation fault in Fenwick tree(Binary Index Tree)

I've realised Fenwick Tree, but when i try to find sum on segment there is Segmentation Fault 11.
#include <vector>
#include <iostream>
using namespace std;
class Fenwick{
public:
Fenwick();
int sum(int l, int r);
void update(int pos, int value);
void print(int i);
private:
vector<int> fentr;
int sum(int i);
};
Fenwick::Fenwick(){
}
void Fenwick::print(int i){
cout<<fentr[i];
}
int Fenwick::sum(int l, int r){
return sum(r)-sum(l-1);
}
int Fenwick::sum(int i){
int result=0;
// while(i>=0){
// result+=fentr[i];
// i=(i&(i+1))-1;
// }
for(int j=i; j>=0; j=(i&(i+1))-1){
result+=fentr[j];
}
return result;
}
void Fenwick::update(int pos, int value){
while (pos<fentr.size()){
fentr[pos]+=value;
pos=pos | (pos+1);
}
}
int main(){
Fenwick a;
a.update(0, 1);
a.update(1, 2);
a.update(2, 3);
a.update(3, 4);
a.update(4, 5);
int j = a.sum(0,2);
cout<<j;
}
Also, have i done it right? I mean, i completely understood idea of Fenwick tree, I just can't find out what we must do with initial array? May be i need to pass as an argument to Fenwik class and then working with him? Or just a lot of updates? Thank you in advance.
As far as I can see, you haven't initialized the fentr vector. This won't fail on update, since you're looping to fentr.size(), but it will segfault on the call to sum.