Suffix Array sort function - c++

Here I am trying to use inbuilt sort function. 's' is the array which stores the index. I am trying to sort this array according to suffix strings. If I am using qsort() function it works fine. But as soon as sort() used it sorts simply s array, doesn't recognize sort according to the suffixes in str. Please suggest me suitable changes for sort function. qsort() function is denoted in comment.
here is my code
string str;
int s[50005];
long long l;
//for qsort()
int cmp(const void *a,const void *b)
{
return (strcmp((str+ *((int*)a)),(str+ *((int*)b))));
}
//for sort() this does not works fine
int cmp1(int a,int b)
{
return (strcmp((str.c_str()+ a),(str.c_str()+ b)));
}
code for suffix array
void suffix_array(int n)
{
int i;
//initially 's' is initialized with all index
for(i=0;i<n;i++)
s[i]=i;
// qsort(s,n,sizeof(int),cmp); this works fine
sort(s,s+n,cmp1);
}
main function
int main()
{
int n,c;
scanf("%d",&n);
while(n--) {
cin>>str;
//scanf("%s",str);
l = str.length();
suffix_array(l);
for(int i=0;i<l;i++)
cout<<s[i]<<" ";
}
return 0;
}

Related

Why am I getting the wrong output for this C++ code? (one of the problem of hackerrank)

This is the program for printing out sum of array elements. It is showing run time error. The output is coming out to be 0 instead of printing out the sum of the elements.
#include<iostream.h>
using namespace std;
void simpleArraySum()
{
int ar[100],n,i,sum=0;
for(i=0;i<n;i++)
{
sum=sum + ar[i];
}
cout<<sum;
}
int main()
{
int ar[100],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ar[i];
}
simpleArraySum();
return 0;
}
On this line in your main:
int ar[100], n;
You create an array of 100 elements. You later fill that array using cin
for(int i = 0 ; i < n ; i++)
{
cin >> ar[i];
}
Then you do nothing with that array. You are not calculating any sum. You let that array go, forgotten.
Then, you call a simpleArraySum function. That function is creating an entirely new, distinct array.
// v-----v------There
int ar[100],n,i,sum=0;
That array has no value assigned to it. In fact, reading from it is undefined behavior.
What you want is to receive that array in the arguments of your function:
void simpleArraySum(int* ar, int n) {
// ...
}
And call it like that in your main:
simpleArraySum(ar, 100);
You can avoid the issues of arrays and functions by not using them:
int main()
{
int quantity = 0;
std::cin >> quantity;
int sum = 0;
int value;
while (std::cin >> value)
{
sum += value;
}
std::cout << sum << "\n";
return EXIT_SUCCESS;
}
In simpleArraySum, the variable n is uninitialized. So this loop:
for(i=0;i<n;i++)
invokes undefined behavior when reading from n.
Also, you are summing a different array in the function, than the one you read in mian. It seems that you need to pass in the array from main to this function:
void simpleArraySum(int *ar, int n) {
and call it like this:
simpleArraySum(ar, n);
Finally, you don't even need a function for this, since there is an existing algorithm std::accumulate that you can use:
cout << std::accumulate(ar, ar + n, 0);
In the function, you're adding the elements of ar which is local to the function simpleArraySum() and is not of the array ar that is local to main().
So, pass the array and its length to the function and return its sum. Here is your corrected code:
#include<iostream>
using namespace std;
void simpleArraySum(int ar[], int n)
{
int i, sum = 0;
for(i=0;i<n;i++)
{
sum=sum + ar[i];
}
cout<<sum;
}
int main()
{
int ar[100],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ar[i];
}
simpleArraySum(ar, n);
return 0;
}

Is there any solution of the error of sorting user input array using STL?

My code is:
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
struct Interval
{
int init,last;
};
bool compare(Interval a,Interval b)
{
return (a.init < b.init);
}
int main()
{
int t,i,j;
int a[1000];
cin >> t;
for( j=0;j<t;++j){
for(i=0;i<t;i++)
{
cin >> a[i];
}
}
sort(a,a+t,compare);
for( j=0;j<t;++j)
for(i=0;i<t;i++)
{
cout<<a[i]<<" ";
}
cout<<"\n";
return 0;
}
What is the solution of the below line?
sort(a,a+t,compare);
The problem is here
bool compare(Interval a,Interval b)
{
return (a.init < b.init);
}
compare compares Interval objects
But
int a[1000];
sort(a,a+t,compare);
you are trying to sort an int array.
Either sort an int array or an Interval array, but be consistent. The compare function must match the array that you are sorting.
You are attempting to sort int a[1000]; which is an int array, not an Interval array. If this is really your intention, then you do not need the predicate (compare function) for sort. You can simply use the default operator< that is provided for int. That means you code could just be:
std::sort(std::begin(a), std::begin(a) + t);

Need to devise a recursive algorithm for the following problem in c++

A recursive algorithm that gets an integer n and integer array A as input and check if the given array
A contains two integers, such that n= A[i]+A[j] where A[i] & A[j] can be at any position in array.
This is what I have come up with
#include <iostream>
using namespace std;
void func(int arr[],int size,int n)
{
if (size==1)
return;
else
{
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
if (arr[i]+arr[j]==n)
{
cout<<"yes";
return;
}
func(arr,size-1,n);
}
}
int main()
{
int A[] = {1,2,3,4,5};
int n = 8;
func(A,5,n);
return 0;
}
I know it's using recursion but I want a recursive function that avoids all unnecessary iterations. Any help will be greatly appreciated!!
#include <iostream>
using namespace std;
void func(int arr[],int index,int size,int n)
{
if(index==size-1)
return;
int flag=0;
for (int j=index+1;j<size;j++)
if (arr[index]+arr[j]==n)
{
flag=1;
cout<<"yes";
}
if(flag==0)
func(arr,index+1,size,n);
}
int main()
{
int A[] = {1,2,3,4,5};
int n = 6;
func(A,0,5,n);
return 0;
}
If you really want a recursive code, this may be one kind of implementation. All i have done is start from 0th index and sum it with every other element and compare it with with 'n'. If it matches fine otherwise make a recursive call with next index(prev index + 1).

How to set vector values from 0 index?

I have initialized the array with n elements in the constructor of Array class. Now, if I want to set the values of these elements, then by using 'set function', values are getting set after n+1 index. How do I set the values from 0 index of vector?
#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;
class Array{
vector<int> array;
public:
Array(int n):array(n){}
int binarySearch(int n,int i,int f)
{
int mid= (i+f)/2;
if(i!=f || array[mid]==n){
if(array[mid] == n)
return mid;
else if(array[mid] < n)
return binarySearch(n,mid+1,f);
else
return binarySearch(n,i,mid-1);
}
else
return NULL;
}
int set(int n){
array.push_back(n);
}
int size(){
return array.size();
}
void print(){
int i=0;
while(i<array.size()){
cout<<array[i]<<endl;i++;
}
}
};
int main()
{
cout<<"ENter no. of element for the array to be initialized with"<<endl;
int n,x;
cin>>n;
Array a(n);
for(int i=0;i<n;i++){
cin>>x;
a.set(x);
}
cout<<"Enter the no. to be searched"<<endl;
cin>>x;
cout<<a.binarySearch(x,0,a.size());
return 1;
}
push_back pushes to the back of the array, i.e appends after the n elements that you create in the constructor. You can use [] operator to set the elements individually. Or if you are setting them all to the same, I think there is a constructor for that.
no need to create the a Array with n objects..
simply get n numbers from the users and use the set method to push them into the vector

passing modified array values back to main function in C++

Write a reverse function that takes an integer array and its length as arguments. Your
function should reverse the contents of the array, leaving the reversed values in the original
array, and return nothing.
#include<iostream>
using namespace std;
void printArray(int a[], const int n)
{
for(int i=0;i<n;i++)
{
cout<<a[i];
i!=n-1 ? cout<<", " : cout<<"";
}
}
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
a = reverse;
}
int main()
{
int *a,n;
cin>>n;
a = new int[n];
for(int i=0;i<n;i++)
a[i]=0;
a[0]=1;
reverse(a,n);
printArray(a,n);
delete [] a;
a = NULL;
return 0;
}
After calling reverse function the array from main is not modifying, please advice! :(
You can't assign one array to another. Instead copy from reverse to back into a:
std::copy(reverse, reverse + n, a);
Or possibly
memcpy(a, reverse, n * sizeof(int));
You are not copying the data from reverse back to a - you are instead pointing it (a) to a memory location that will no longer exist (be valid) after your function returns. You need to copy the values from reverse back to a. And I would recommend not using the same name for a function and a variable.
Try
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
for(int i=0;i<n;i++)
{
a[i]=reverse[i];
}
}
As was pointed out in comments, the above shows one way of getting the reversed data into array a. It is not the only way - memcpy is considered a more efficient function to use. Even more efficient would be to do in place reversal - this would require a loop of just n/2 iterations while the above loops for 2n and is thus about 4x less efficient.
I recommend that you study all the answers provided - they highlight different aspects of memory handling, code efficiency etc.; something to learn from all of them.
Pointers! They're really useful.
void reverse (int *a, const size_t n)
{
int *b = a + n - 1;
while (b > a)
{
const int swap_value = *a;
*a = *b;
*b = swap_value;
++a;
--b;
}
}
Aha, you know you should pass int a[], a pointer to a, to reverse(), but you still encounter the same problem. You can't modify the pointer stored in a, unless you pass &a to reverse().