hey everybody i am trying to implement code for finding order statistic but i am getting a error ..in algorithm two variables are passed in random function is there any way to pass two variables in it if yes than how?? and if no then what can be its alternate ... your help will be appreciated
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
int RandomizedSelect(int*,int,int,int);
int RandomizedPartition(int*, int, int);
int partion(int*,int,int);
void main()
{
int n,x,i;
cout<<"Enter length of array";
cin>>n;
int *a=new int[n];
cout<<"Enter elements of array";
for(i=0;i<n;i++)
{
cin>>a[i];
}
cout<<"Enter element less than size of array";
cin>>x;
int z=RandomizedSelect(a,0, n, x);
cout<<z;
getch();
}
int RandomizedSelect(int A[],int p, int r,int i)
{
if (p == r)
{
return A[p];
}
int q = RandomizedPartition(A, p, r);
int k = q - p + 1;
if (i == k)
{
return A[q];
}
else if (i < k)
{
return RandomizedSelect(A, p, q-1, i) ;
}
else return RandomizedSelect(A, q+1, r, i - k);
}
int Partition(int A[],int p,int r)
{
int x=A[r],temp;
int i=p-1,j;
for(j=p;j<r-1;j++)
{
if(A[j]<=x)
{
i++;
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
temp=A[i+1];
A[i+1]=A[r];
A[r]=temp;
return i+1;
}
int RandomizedPartition(int A[],int p,int r)
{
int temp;
int j = random(p,r);
temp=A[r];
A[r]=A[j];
A[j]=temp;
return Partition(A, p, r);
}
Above code is not working in some case.Here is the corrected code. Below code is working properly I have checked for all cases.
#include<iostream>
#include<cstdlib>
using namespace std;
int RandomizedSelect(int*,int,int,int);
int RandomizedPartition(int*, int, int);
int partion(int*,int,int);
int main()
{
int n,x,i;
cout<<"Enter length of array: ";
cin>>n;
int *a=new int[n];
cout<<"Enter elements of array: ";
for(i=0;i<n;i++)
{
cin>>a[i];
}
cout<<"Enter element less than size of array: ";
cin>>x;
int z=RandomizedSelect(a,0, n-1, x);
cout<<z;
}
int RandomizedSelect(int A[],int p, int r,int i)
{
if (p == r)
{
return A[p];
}
int q = RandomizedPartition(A, p, r);
int k = q - p + 1;
if (i == k)
{
return A[q];
}
else if (i < k)
{
return RandomizedSelect(A, p, q-1, i) ;
}
else return RandomizedSelect(A, q+1, r, i - k);
}
int Partition(int A[],int p,int r)
{
int x=A[r],temp;
int i=p-1,j;
for(j=p;j<r;j++)
{
if(A[j]<=x)
{
i++;
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
temp=A[i+1];
A[i+1]=A[r];
A[r]=temp;
return i+1;
}
int RandomizedPartition(int A[],int p,int r)
{
int temp;
int j = p + rand()%(r-p+1);
temp=A[r];
A[r]=A[j];
A[j]=temp;
return Partition(A, p, r);
}
To select a random value between p and r, you may use this formula:
p + rand()%(r-p+1);
rand() gives you a pseudo-random integer value in [0, RAND_MAX]. Then you take the remainder (%), thus converting to a value in [0, r-p] (as long as r-p+1 is less than RAND_MAX). Adding it to p, you get a value in [p, r].
Related
Can anyone please explain why my Merge Sort code is not working;
CPP;
I used very Normal Approach but still its not working properly.
#include<iostream>
using namespace std;
void merge(int a[], int l, int mid, int r)
{ int p[r];
int i=l;
int j= mid+1;
int k=l;
while(i<=mid && j<=r)
{
if(a[i]<a[j])
{
p[k] = a[i];
i++;
}
else
{
p[k] = a[j];
j++;
}
k++;
}
for(k=l; k<=r; k++)
{
a[k]=p[k];
}
}
void ms(int a[], int l, int r)
{
if(l<r)
{
int mid = (l+r)/2;
ms(a,l,mid);
ms(a, mid+1, r);
merge(a,l,mid,r);
}
}
int main()
{
int a[]={1,9,4,6,2,7};
int l=0; int r=5;
ms(a,l,r);
for(int i=0; i<=r; i++)
{
cout<<a[i];
}
return 0;
}
I learned this code from a youtube tutorial: https://www.youtube.com/watch?v=aDX3MFL0tYs
Its output should be 1,2,4,6,7,9
but it is showing 102700, please help.
I am trying to understand segment trees. I tried a problem on hackerrank (link) and I tried to use the geeksforgeeks code in c++link. However, I got a dump value problem in line 19.
int right = RMQUtil(st, mid+1, se, qs, qe, 2*index+2); // why this is getting a dump value here?
Also I found that this is gonna time out. Is there an other efficient approach to solve this?
I want to know why my code is not efficient to solve this and need to have a better solution in c++
Here's the code I tried.
// you will see the comments on the geeksforgeeks code in the link. I used it here.
#include <bits/stdc++.h>
using namespace std;
int minVal(int x, int y) { return (x < y); }
int getMid(int s, int e) { return s + (e -s)/2; }
int RMQUtil(int *st, int ss, int se, int qs, int qe, int index)
{
if (qs <= ss && qe >= se)
return st[index];
if (se < qs || ss > qe)
return INT_MAX;
int mid = getMid(ss, se);
int left = RMQUtil(st, ss, mid, qs, qe, 2*index+1);
int right = RMQUtil(st, mid+1, se, qs, qe, 2*index+2); // why this is getting a dump value here?
return min({left, right, left+right},minVal);
}
int RMQ(int *st, int n, int qs, int qe)
{
if (qs < 0 || qe > n-1 || qs > qe)
{
cout<<"Invalid Input";
return -1;
}
return RMQUtil(st, 0, n-1, qs, qe, 0);
}
int constructSTUtil(int arr[], int ss, int se, int *st, int si)
{
if (ss == se)
{
st[si] = arr[ss];
return arr[ss];
}
int mid = getMid(ss, se);
int left = constructSTUtil(arr, ss, mid, st, si*2+1);
int right = constructSTUtil(arr, mid+1, se, st, si*2+2);
st[si] = min({left, right, left+right},minVal);
return st[si];
}
int *constructST(int arr[], int n)
{
int x = (int)(ceil(log2(n)));
int max_size = 2*(int)pow(2, x) - 1;
int *st = new int[max_size];
constructSTUtil(arr, 0, n-1, st, 0);
return st;
}
void updateSTUtil(int* st, int si, int ss, int se, int k, int v){
if (k < ss or k > se)
return;
if (ss == se){
st[si] = v;
return;
}
int mid = getMid(ss, se);
updateSTUtil(st, 2 * si +1, ss, mid, k, v);
updateSTUtil(st, 2 * si +2, mid + 1, se, k, v);
st[si] = min({st[2 * si +1], st[2 * si +2], st[2 * si +1] + st[2 * si +2]}, minVal);
}
void updateST(int n, int* st, int k, int v){
updateSTUtil(st, 0, 0, n-1, k, v);
}
int main()
{
int t,n,q,a,ss,se;
scanf("%d",&t);
for (int i=0; i<t; i++){
scanf("%d",&n);
int arr[n];
for (int j=0 ; j<n; j++){
cin >> arr[j];
}
int *st = constructST(arr, n);
scanf("%d",&q);
for (int i=0; i<q; i++){
scanf("%d%d%d",&a,&ss,&se);
if (a == 0){
updateST(n, st, ss-1, se);
}
else{
cout << RMQ(st, n, ss-1, se-1)<<endl;
}
}
}
return 0;
}
:)
Check Binary indexed tree or Fenwick tree .
Check this
https://www.geeksforgeeks.org/binary-indexed-tree-range-update-range-queries/
And a
maybe interval tree according to what you want for eg. if you want to find maximum or minimum in range.
#include<iostream>
#define INF 10000
using namespace std;
void mergeSort(int *x,int y,int z);
void merge(int *a,int p,int q,int r);
void main()
{
int i,size;
cin>>size;
int arr[size];
for(i=0;i<size;i++)
{
cin>>arr[i];
}
mergeSort(arr,0,size-1);
for(i=0;i<size;i++)
{
cout<<arr[i]<<endl;
}
}
This function takes in the array to be sorted and the values of starting and ending index i.e, y,z.
void mergeSort(int *x,int y,int z)
{
int q;
if(y<z)
{
q=(y+z)/2;
mergeSort(x,y,q);
mergeSort(x,q+1,z);
merge(x,y,q,z);
}
}
this function merges two sorted sections of the array and p,r are starting and ending index while q is the index which divides the array into two sorted parts
void merge(int *a,int p,int q,int r)
{
int l1,l2,i,j;
l1=q-p+1;
l2=r-q;
int left[l1+1],right[l2+1];
for(int i=0;i<l1;i++)
{
left[i]=a[p+i];
}
for(int j=0;j<l2;j++)
{
right[i]=a[q+j];
}
left[l1+1]=INF;
right[l2+1]=INF;
i=0;
j=0;
for(int k=0;k<=r-p;k++)
{
if(left[i]<right[j])
{
a[k]=left[i++];
}
else
{
a[k]=right[j++];
}
}
}
You have tried to access an out of bounds index in the following lines (in merge() subroutine):
left[l1 + 1] = INF;
right[l2 + 1] = INF;
The size is l1+1 and l2+1 respectively. So, the range of valid indices will be [0, l1] and [0, l2]. The lines should thus be:
left[l1] = INF;
right[l2] = INF;
The final problem is in the line:
for(int k = 0; k <= r-p; k++)
which should be
for(int k = p; k <= r; k++)
otherwise, you will just overwrite the other values. You have to insert the merged part at the proper position.
I have written the solution of a C++ problem which should show an ordered array with values from a matrix. I have done it, but it keeps showing two errors and I can't figure out how to solve them.
The errors are:
Line 84|error: invalid initialization of reference of type 'int&' from expression of type 'int*'|
Line 57|error: in passing argument 1 of 'void Inserare(int&, int*, int)'|
#include <iostream>
#include <math.h>
using namespace std;
void CitireMatrice(int& n,int mat[100][100])
{
int i,j,m;
cout<<"Da n ";
cin>>n;
m=n;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cout<<"Matricea["<<i<<"]["<<j<<"]=";
cin>>mat[i][j];
}
}
void Tiparire(int n,int X[])
{ int i;
if(n!=0)
{
for(i=1;i<=n;i++)
cout<<X[i]<<" ";
cout<<endl;
}
else
cout<<"Sirul este vid";
}
int Prim(int n)
{
int div=2;
while(div<=sqrt(n) && n%div!=0)
{
if(div == 2)
div = 3;
else
div = div + 2;
}
return div;
}
int SuperPrim(int n)
{
while(n!=0)
{
if(Prim(n)==0)
return 0;
n=n/10;
}
return 1;
}
void Inserare(int& n,int X[],int v)
{ int i;
int p=1; //prima pozitie
while(X[p]>v && p<=n)
p++;
for(i=n;i>=p;i++)
X[i+1]=X[i];
X[p]=v;
n++;
}
int Apartine(int X[],int n,int v)
{ int i;
int gasit=0; //initializat cu 0 deoarece nu a gasit nimic inca
for(i=1;i<=n;i++)
if(X[i]==v)
gasit=1;
return gasit;
}
void Construire(int n,int mat[100][100],int X[],int& k)
{ int i,j;
k=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if((i>j && i+j<n+1) || (i<j && i+j>n+1)) //daca apartine triunghiului drept SAU strang
if(SuperPrim(mat[i][j])==1 && Apartine(X,k,mat[i][j])==0)
Inserare(X,k,mat[i][j]);
}
int main()
{
int m,n,mat[100][100],X[100],k;
CitireMatrice(n,mat);
Construire(n,mat,X,k);
Tiparire(n,X);
return 0;
}
Inserare(X,k,mat[i][j]);
X is table address and according to declaration
void Inserare(int& n,int X[],int v)
you should pass reference. maybe you wanted to switch X and k in your call?
You have the function void Inserare(int& n,int X[],int v), and you try to call Inserare(X,k,mat[i][j]);.
You are probably trying to send the parameters in the wrong order. Try to change your call on Inserare(k,X,mat[i][j]);
The code that I have made for merge sort is given below. The thing is that on giving the input the output is 3 2 1 5 0. What is going wrong?
#include <iostream>
#include <cmath>
using namespace std;
int d[100];
void merge(int a[], int b[], int c[], int n)
{
int n2=floor(n/2);
int i=0, j=0, k=0;
while(i<n2 && j<(n-n2))
{
if(b[i]<c[j])
{
d[k++]=b[i++];
}
else if(b[i]>c[j])
{
d[k++]=c[j++];
}
}
if(i==n2)
{
if(j<(n-n2))
{
d[k++]=c[j++];
}
}
if(i<n2)
{
d[k++]=b[i++];
}
}
void mergesort(int a[], int n)
{
int n2=floor(n/2);
int b[50],c[50];
int i,j=0,k=0;
for(i=0;i<n2;i++)
{
b[i]=a[k++];
}
while(k<n)
{
c[j++]=a[k++];
}
merge(a,b,c,n);
}
int main()
{
int a[]={5,4,3,2,1};
int n=5;
mergesort(a,n);
for(int i=0;i<n;i++)
{
cout<<d[i]<<endl;
}
}
The main problem is that the arrays (b and c) passed to merge are not sorted.
Other problems are that the algorithm is not recursive and that merge
does not always put all numbers from b and c into a.
A version that seems to work with minimal changes to your code would be
void merge(int a[], int b[], int c[], int n)
{
int n2=floor(n/2);
int i=0, j=0, k=0;
while(k<n)
{
if((j == (n-n2) || b[i]<c[j]) && i < n2)
{
a[k++]=b[i++];
}
else
{
a[k++]=c[j++];
}
}
}
void mergesort(int a[], int n)
{
int n2=floor(n/2);
int b[50],c[50];
int i,j=0,k=0;
for(i=0;i<n2;i++)
{
b[i]=a[k++];
}
while(k<n)
{
c[j++]=a[k++];
}
if(n2 > 1) {
mergesort(b, n2);
}
if(n - n2 > 1) {
mergesort(c, n - n2);
}
merge(a,b,c,n);
}
int main()
{
int a[]={5,4,3,2,1};
int n=5;
mergesort(a,n);
for(int i=0;i<n;i++)
{
cout<<a[i]<<endl;
}
}
It is conventional to call merge_sort recursively in order to sort each subrange until the subrange is just one long then merge these together.
In your mergesort, b takes the first n/2 values of a, that is 5 and 4.
c takes the remaining values 3,2,1.
You then call merge (BTW Why do you pass a[] to this? It isn't used)
The first loop
while(i<n2 && j<(n-n2))
will have n2 = 2 and n-n2 = 5-2 = 3
This puts 3 at the start since b[0]>c[0]=3 and 2 next since b[1]>c[1]=2 and 1 at d[2] for similar reasons.
Since you don't recurse you won't sort these.
You then finish the while loop with i = 0 which is less than n2.
You just say
if(i<n2)
so you just copy the first thing from b which is 5.
All this gives 3, 2, 1, 5, and 0 because you made d global.
The input for merge need to be sorted arrays, as Philip mentioned before. Mergesort is recursive. For this you need to divide them till you reach a point where you only have one element in the array (so it is sorted) and merge all arrays to become the sorted result for the input. Wikipedia is your friend to understand the algorithm: Mergesort
Btw: You need to ensure that one of both cases in the comparison in the merge checks also on equality of the values.
Philip is right, there's no recursive in your code at all.
However, there are some more errors. I've marked it with annotations, just as a postscript of Philip's.
#include <iostream>
#include <cmath>
using namespace std;
int d[100];
void merge(int a[], int b[], int c[], int n)
{
int n2=floor(n/2);
int i=0, j=0, k=0;
while(i<n2 && j<(n-n2))
{
if(b[i]<c[j])
{
d[k++]=b[i++];
}
else if(b[i]>c[j])
{
d[k++]=c[j++];
}
/***************************************************/
/* What if b[i] == c[j] here? */
/* Your code will drop into an infinity loop. */
/***************************************************/
}
if(i==n2)
{
if(j<(n-n2))
/****************************************************/
/* Use **while** here? */
/* Because there may be more than one elements left */
/* in c[]. */
/****************************************************/
{
d[k++]=c[j++];
}
}
if(i<n2)
/***************************************************/
/* Use **while** here? - With the same reason */
/***************************************************/
{
d[k++]=b[i++];
}
}
void mergesort(int a[], int n)
{
int n2=floor(n/2);
int b[50],c[50];
int i,j=0,k=0;
for(i=0;i<n2;i++)
{
b[i]=a[k++];
}
while(k<n)
{
c[j++]=a[k++];
}
merge(a,b,c,n);
}
int main()
{
int a[]={5,4,3,2,1};
int n=5;
mergesort(a,n);
for(int i=0;i<n;i++)
{
cout<<d[i]<<endl;
}
}
template <typename T>
void merge(T arr[], int begin, int mid, int end)
{
int len = end - begin;
T *temp = new T[len];
int i = begin;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= end)
{
if(arr[i] <= arr[j])
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
}
while (i <= mid)
temp[k++] = arr[i++];
while(j <= end)
temp[k++] = arr[j++];
memcpy(arr + begin, temp, len*sizeof(T));
delete []temp;
}
template <typename T>
void mergeSort(T arr[], int begin, int end)
{
if (begin >= end)
return;
int mid = (end + begin) / 2;
mergeSort(arr, begin, mid);
mergeSort(arr, mid + 1, end);
merge(arr, begin, mid, end);
}