Implementing binomial heap - c++

My aim is to construct a binomial heap. Here is my code which i have written right now:
#include<iostream>
using namespace std;
void maxheapify(int a[],int length,int i)
{
int left=2*i;
int right=2*i+1;
int largest=i;
if(left<length && a[left]>a[largest])
{
largest=left;
}
if ( right<length && a[right]>a[largest])
{
largest=right;
}
if(largest!=i)
{
int temp=a[i];
a[i]=a[largest];
a[largest]=temp;
maxheapify(a,length,largest);
}
}
void buildmax(int a[],int length)
{
for(int i=(length-1)/2;i>=0;i--)
{
maxheapify(a,length,i);
}
}
/*void heapsort(int a[],int length)
{
buildmax(a,length);
for(int i=length-1;i>0;i--)
{
int temp=a[i];
a[i]=a[0];
a[0]=temp;
maxheapify(a,i,0);
}
}
*/
void combine_heap(int a[],int n,int b[],int m,int c[])
{
}
int main()
{
int a[100];
int n=sizeof(a)/sizeof(a[0]);
int b[100];
int m=sizeof(b)/sizeof(b[0]);
int c[200];
int length=sizeof(a)/sizeof(a[0]);
for(int i=0;i<length;i++){
a[i]=34+rand()%(length-33);
b[i]=rand()%(i+1);
}
/*heapsort(a,length);*/
/*for(int i=0;i<length;i++)
cout<<a[i]<<" ";*/
return 0;
}
i think trivial solution would be to combine two array into third one and then call buildmax procedure,but i think it is not efficient,i have tried to implement this pseudo code from wikipedia
function merge(p, q)
while not( p.end() and q.end() )
tree = mergeTree(p.currentTree(), q.currentTree())
if not heap.currentTree().empty()
tree = mergeTree(tree, heap.currentTree())
heap.addTree(tree)
else
heap.addTree(tree)
heap.next() p.next() q.next()
but i dont know how to implement it,because in generally how to access subtrees?another variant is construct priority queue and by using insert function insert first from one array and then from another array,but is this optimal?please help me to write code to combine these two max heap into one efficiently

This is a good example of Binomial Heap but it is in c. You will get the basic logic to implement binomial heap. See Example here
Or get video tutorial to here to understand algorithm.

Related

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;
}

I have written a code to find reverse of array elements but it doesnot gives required output

# include <iostream>
using namespace std;
const int size=5;
void inputdata(int arr[], int n); //function prototype
void display(int arr[],int n); //function prototype
void Reverse(int arr[],int n); //function prototype
int main() //start of main function
{
int list[size]; //array declaration
inputdata(list ,size); //fuction call
display(list,size); //fuction call
Reverse(list,size); //fuction call
}
void inputdata(int arr[], int n) //function definition that takes input from user
{
int index;
for(index=0;index<n;index++) //loop to take input from user
{
cout<<"Enter element ["<<index<<"]"<<endl;
cin>>arr[index];
}
}
void display(int arr[],int n) //displays the input
{
int index;
for(index=0;index<n;index++) //loop to display output
{
cout<<"Element on ["<<index<<"] is:"<<arr[index]<<endl;
}
}
void Reverse(int arr[],int n) //function to find reverse
{
int i,temp; //here i have taken a variable temp of integer type for swapping
for(i=0;i<n/2;i++)
{
temp=arr[i];
arr[i]=arr[n-i-1];
arr[n-i-1]=arr[i];
}
cout<<"the reverse order array is:"<<endl;
for(i=0;i<n;i++) //this loop is used to display the reverse order
{
cout<<arr[i]<<endl;
}
return 0;
}
this above c++ code is meant to find the reverse of the elements of array which is taken as input from user.Input data function is used to take input from the user.Display function is used to display that input.Then there is a function reverse which finds the reverse.
But it does not gives proper reverse(output) e.g if i enter 5 array elements as 1,2,3,4,5 its output should be as 5,4,3,2,1.But this results as 5,4,3,4,5.
Your swap code looks like:
temp=arr[i];
arr[i]=arr[n-i-1];
arr[n-i-1]=arr[i];
But it should be:
temp=arr[i];
arr[i]=arr[n-i-1];
arr[n-i-1]=temp;
A cleaner and simpler option would be to use the swap function in the algorithm library.

Finding LCS using DP

I have used Dynamic Programming to find longest common sub-sequence b/w two strings. What is wrong in the code. Why it always gives answer as 0?
#include<bits/stdc++.h>
using namespace std;
int dp[20][20];
void initialize()
{
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
dp[i][j]=-1;
}
int lcs(string a,string b,int m,int n)
{
if(m==0||n==0)
return 0;
if(dp[m][n]!=-1)
return dp[m][n];
if(a[m-1]==b[n-1])
return dp[m-1][n-1] = 1+lcs(a,b,m-1,n-1);
if(a[m-1]!=b[n-1])
return dp[n-1][m-1]=max(dp[n][m-1]=lcs(a,b,n,m-1),dp[n-1][m]=lcs(a,b,n-1,m));
}
int main()
{
string a="AGGTAB",b="GXTXAYB";
cout<<lcs(a,b,a.length(),b.length());
}
You've forgotten to call initialize()
18th line, it should be dp[m][n], not dp[m-1][n-1]
Commented 19th line code, as it is no need & for make the code compatible for all compilers
i.e., some compiler may give warning: control reaches end of non-void function [-Wreturn-type]
Made some code change in 20th line, as it seems you confused with variables m & n.
Code:
#include<bits/stdc++.h>
using namespace std;
int dp[20][20];
void initialize()
{
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
dp[i][j]=-1;
}
int lcs(string a,string b,int m,int n)
{
if(m==0||n==0)
return 0;
if(dp[m][n]!=-1)
return dp[m][n];
if(a[m-1]==b[n-1])
return dp[m][n] = 1+lcs(a,b,m-1,n-1);
//if(a[m-1]!=b[n-1])
return dp[m][n]=max(lcs(a,b,m-1,n),lcs(a,b,m,n-1));
}
int main()
{
string a="AGGTAB",b="GXTXAYB";
initialize();
cout<<lcs(a,b,a.length(),b.length());
}
Output:
4

Unable to access vector value by index

#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.

bsort implementation from programming pearls

This question is a follow-up to a question I asked earlier on Stack Overflow:
bsort example from programming pearls
I want to show you my work and have some questions about it.
#include<string.h>
#include<iostream>
using namespace std;
void swap(char *x[],int i,int j)
{
char *t=x[i];
x[i]=x[j];
x[j]=t;
}
int get_bit(char *s,int depth)
{
int required_bit=13;
int bit=required_bit&0x7;
int byte=required_bit>>3;
int val=(s[byte]>>bit)&0x1;
return val;
}
void bsort(char *x[],int l,int u,int depth)
{
if(l>=u) return ;
for(int i=l;i<=u;i++){
if(strlen(x[i])<depth){
swap(x,i,l++);
}
}
int m=l;
for(int i=l;i<u;i++)
{
if(get_bit(x[i],depth)==0)
{
swap(x,i,m++);
}
}
bsort(x,l,m-1,depth+1);
bsort(x,m,u,depth+1);
}
int main()
{
char *x[6]={"car","bus","snow","earth","dog","mouse"};
bsort(x,0,5,1);
for(int i=0;i<6;i++)
cout<<x[i]<<" "<<endl;
return 0;
}
The code above works, compiles and shows me a result. But I am interested to know whether it sorts lexicographically or otherwise? The result is this:
car
bus
dog
snow
earth
mouse
First b is before c, so are car and bus on the right place? Please tell me what is wrong with my code.