Hi I have written a program for Least common subsequence problem,
and stuck with 2-dim array passing and traversal. kindly helpy.
Following is the piece of code.
void backtrack(char x[], char y[], int L[][7], int m, int n)
{
if(m == 0 || n == 0)
return;
else if(x[m-1] == y[n-1])
{
backtrack(x, y, L, m-1, n-1);
cout << x[m-1] << " ";
}
else
{
if(L[m-1][n] > L[m][n-1])
backtrack(x, y, L, m-1, n);
else
backtrack(x, y, L, m, n-1);
}
}
int lcs_length(char x[], char y[], const int m, const int n)
{
int L[m+1][n+1];
for(int i=0; i<=m; i++)
{
for(int j=0; j<=n; j++)
{
if(i == 0 || j == 0)
L[i][j] = 0;
else if (x[i-1] == y[j-1])
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = max (L[i-1][j], L[i][j-1]);
}
}
backtrack(x, y, L, m+1, n+1);
return L[m][n];
}
int main(int argc, char *argv[])
{
char x[] = "ABCDGH";
char y[] = "AEDFHR";
int m = sizeof x / sizeof *x;
int n = sizeof y / sizeof *y;
cout << lcs_length(x, y, m, n);
return EXIT_SUCCESS;
}
I am basically stuck in calling backtrack function from lcs_length() as I am not able to pass / traverse the 2-dim array within backtrack...
kindly help..
thanks.
Your two-dimensional array L in lcs_length is not a real c-array because you use variables to set the number of elements. When setting its size e.g. to int L[100][7] everything works fine.
But to solve your problem I would rather use a real dynamic array, for example: int **L = new int* [m+1];
for (int i = 0; i < m+1; i++)
L[i] = new int[n+1];
Then you can pass the array as int ** L.
Related
void swap(int a[], int x, int y)
{
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
void sort(int arr[], int x)
{
static int count = 0;
if (x == 1)
{
return;
}
int min = 100; // random value
int index;
for (int i = 0; i < x; i++)
{
if (arr[i] < min)
{
min = arr[i];
index = i;
}
}
swap(arr, count, index);
count++;
sort(arr + 1, x - 1);
}
int main()
{
int x;
cin >> x;
int A[x];
for (int i = 0; i < x; i++)
{
cin >> A[i];
}
sort(A, x);
for (int i = 0; i < x; i++)
{
cout << A[i] << " ";
}
cout << endl;
return 0;
}
this code is of selection sort using recursion. It is printing garbage values. what's the mistake in this. i am not sure but i guess because of using the static variable in the sort function(). it is printing garbage values
Replace swap(arr, count, index); with
swap(arr, 0, index);
and remove static int count = 0;.
Replace sort(A, x); in the main with
sort(A, x - 1);
and change the condition if (x == 1) to if (x == 0).
I suggest to rename index to last.
Replace min = 100; with
min = arr[0];
For starters variable length arrays like this
int x;
cin >> x;
int A[x];
is not a standard C++ feature.
Nevertheless the function can invoke undefined behavior when for example is called with the second parameter equal to 0.
Also there is no sense to declare the static variable.
The function will not sort an array elements of which have values greater than 100.
The variable index must be initialized to 0 before the for loop.
Also there is already the standard function std::swap that swaps two objects.
The function can be defined the following way
#include <algorithm>
void selection_sort( int a[], size_t n )
{
if ( not ( n < 2 ) )
{
auto it = std::min_element( a, a + n );
if ( it != a ) std::iter_swap( a, it );
selection_sort( a + 1, n - 1 );
}
}
If you do not know yet standard algorithms then the functions can look the following way
void swap( int &a, int &b )
{
int rmp = a;
a = b;
b = tmp;
}
void selection_sort( int a[], size_t n )
{
if ( not ( n < 2 ) )
{
size_t index = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[i] < a[index] ) index = i;
}
if ( index != 0 ) swap( a[0], a[index] );
selection_sort( a + 1, n - 1 );
}
}
One of the easy ways of doing the selection sort using recursion is as follows:
#include<iostream>
using namespace std;
void selectionSort(int *arr, int size,int minIndex){
//base case
if(size ==0 || size ==1 || minIndex == size){
return;
}
//processing
for(int i=minIndex+1;i<size;i++){
if(arr[i]<arr[minIndex]){
swap(arr[minIndex], arr[i]);
}
}
//recursive call
selectionSort(arr,size,minIndex+1);
}
int main(){
int arr[7]={7,6,5,4,3,2,1};
int size = 7;
int minIndex = 0;
selectionSort(arr,size,minIndex);
for(int i=0;i<7;i++){
cout<<arr[i]<<" ";
}
}
We are creating a minIndex at the starting of the array and comparing it with the values in the remaining array, to get the minimum value of the whole array on the left-most side. At each recursive call, we will increment the place of minIndex for further comparison. Hope this helps.
a=[6,5,4,3,2,1,0,-1]
length=a.length
cur=0
n=cur+1
function fun(n)
{
if(cur==length-1)
{
return a
}
else if(a[cur]>a[n])
{
temp=a[cur]
a[cur]=a[n]
a[n]=temp
if(n==length-1)
{
n=cur
cur++
}
// console.log(a)
// console.log(cur)
return fun(n+1)
}
else
{
if(n==length-1)
{
n=cur
cur++
}
return fun(n+1)
}
}
let t=[]
t=[...fun(n)]
console.log(t)
Recently I learnt about the array rotation in linear time using Juggling algorithm. Here is the snippet regarding the left rotation of the array.
void ArrayRotate (int A[], int n, int k)
{
int d=-1,i,temp,j;
for(i=0;i<gcd(n,k);i++)
{
j=i;
temp=A[i];
while(1)
{
d=(j+k)%n;
if(d==i)
break;
A[j]=A[d];
j=d;
}
A[j]=temp;
}
}
but now I am stuck as how to use this Juggling algorithm to rotate the array in the Right Direction.
1,2,3,4,5 (given array)
5,1,2,3,4 (after 1 right rotation)
(I had solved this question using the brute force method and reversal method.)
As already mentioned, you should use std::rotate if you are allowed to.
Your implementation has a bug. Here is a fixed implementation.
void ArrayRotate(int A[], int n, int k) {
int d = -1, i, temp, j;
int g = gcd(n, k);
for (i = 0; i < g; ++i) {
j = i;
temp = A[i];
while (true) {
d = (j + k) % n;
if (d == i) {
break;
}
A[j] = A[d];
j = d;
}
A[j] = temp;
}
}
Also note that I took out gcd calculation out of loop condition. It does not technically affect complexity, but it's enough to compute the gcd only once.
To rotate the array k times to the right, just rotate it n - k times to the left.
void ArrayRotateRight(int A[], int n, int k) {
ArrayRotate(A, n, n - k);
}
Or change the 8th line to be d = (j - k + n) % n;
Not sure if you're doing this as an intellectual exercise, or for production code, but for production code use the STL rotate algorithm:
#include<iostream>
#include<algorithm>
using namespace std;
void display(int* a, int length)
{
for (int i = 0; i < length; ++i)
cout << a[i] << " ";
cout << endl;
}
int main()
{
const int len = 5;
int arr[] = { 1,2,3,4,5 };
display(arr, len);
rotate(arr, arr + 1, arr + len); // arr + x means left by x
display(arr, len);
rotate(arr, arr + len - 1, arr + len); // arr + len - x means right by x
display(arr, len);
}
I'm trying to find the sum of the numbers in a char array.
My code works for most cases. Example : a=dasn344wee22ee, the output is:366 - which is good
But when my char is,for example : andre54e5 the output should be 59, but the program displays: 108.
Can anybody tell me what the issue is?
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
using namespace std;
int getnr(char a[], int i, int j)
{
int counter = 0;
char sir[1000];
for (int x = i; x<j; x++)
{
sir[counter] = a[x];
counter++;
}
return atoi(sir);
}
int main()
{
char a[1000];
int s = 0, inceput, finals;
cin.getline(a, 255);
for (int i = 0; i<strlen(a); i++)
{
if (isdigit(a[i]) )
{
if (i == strlen(a) - 1)
{
s += getnr(a, i, strlen(a));
}
for (int j = i + 1; j<strlen(a); j++)
{
if (!isdigit(a[j]) || j == strlen(a) - 1)
{
s += getnr(a, i, j + 1);
i = j;
break;
}
}
}
}
cout << s;
return 0;
}
In your function int getnr(char a[], int i, int j), you forgot to null-terminate string sir, such that atoi(sir) might yield a garbage value (actually the behaviour is undefined). The following should help:
int getnr(char a[], int i, int j)` {
...
sir[counter] = '\0';
return atoi(sir);
}
The problem is that getnr() doesn't add a null terminator to the sir array, so you're getting undefined behavior when you call atoi(sir).
int getnr(char a[], int i, int j)
{
int counter = 0;
char sir[1000];
for (int x = i; x<j; x++)
{
sir[counter] = a[x];
counter++;
}
sir[counter] = '\0';
return atoi(sir);
}
The issue is within this part of code:
if (i == strlen(a) - 1)
{
s += getnr(a, i, strlen(a));
}
Specifically, if your last number is a single digit (which it is), it will always return junk.
So, I would change to only convert the single char of the char array as a digit and at it to the int s.
Edit:
For some reason when doing s+= a[i], I return junk.
But, doing the following, does the trick:
if (i == strlen(a) - 1)
{
string x;
x[0] = a[i];
int l = stoi(x);
s += l;
}
I know that there's a much more effective way, but I'm not sure why s+= a[i] itself returns false numbers.
I need to write function as part of assignment..
I need to compute the number of ways to partition n into the sum of positive integers and I can't use for while or goto
/*
* REQUIRES: n > 0
* EFFECTS: computes the number of ways to partition n into the sum of
* positive integers
* MUST be tree recursive
* Hint: Use a helper function that computes the number of ways to
* partition n using a bounded subset of integers. Then use logic
* similar to count_change() from lecture to divide partitions into
* those that use a specific item and those that do not.
*/
int num_partitions(int n);
I figured a way to print them but unable to count it and my function also needed for loop. Here's function
void print(int n, int * a) {
int i ;
for (i = 0; i <= n; i++) {
printf("%d", a[i]);
}
printf("\n");
}
int integerPartition(int n, int * a, int level,int c){
int first;
int i;
if (n < 1)
{
return c;
}
a[level] = n;
print(level, a);
c++;
first = (level == 0) ? 1 : a[level-1];
for(i = first; i <= n / 2; i++){
a[level] = i;
integerPartition(n - i, a, level + 1,c);
}
}
int num_partitions(int n){
int * a = (int * ) malloc(sizeof(int) * n);
return integerPartition (n, a, 0,0);
}
please help...
here is the count change function
int count_change(int amount, const int coins[], int num_coins) {
if (amount == 0) {
return 1;
} else if​ (amount < 0 || num_coins < 1) {
return 0;
} else {
return
count_change(amount - coins[num_coins - 1], coins, num_coins) +
count_change(amount, coins, num_coins - 1);
}
}
You can do it like this:
#include <conio.h>
#include <iostream>
using namespace std;
int integerPartition(int n, int k);
int main()
{
int n;
cin>>n;
int k =n;
cout<<integerPartition(n,k);
getchar();
return 0;
}
int integerPartition(int n, int k)
{
if(k==0)
return 0;
if(n ==0)
return 1;
if(n<0)
return 0;
return integerPartition(n,k-1) + integerPartition(n-k,k);
}
Inspired from: http://www.programminglogic.com/integer-partition-algorithm/
or you can also use: recurrence formula for partition functions, given on
https://en.wikipedia.org/wiki/Partition_(number_theory)
I am getting two errors in implementing the algorithm from pseudocode:
One of my problems is int L[n1+1]; error: needs to be a constant; cannot allocate constant size 0. The only way to run this is to make the size a number like 10. I may be implementing the psuedocode wrong that is why I included the statement above that. This may be the cause of my next problem.
My other problem is I am printing only one line of code unsorted. My print function is flawless and works for all of the sorting programs. I believe the MERGE function is only running once. I posted the output of the Sort at the bottom.
I have a random number generator for the array A, from 0 to RAND_MAX.
Initial call is MERGESORT(A,1,n);
void MERGE(int *A, int p, int q, int r)
{
int n1 = q-(p+1);
int n2 = r-q;
//psuedocode states, let L[1..n1+1] & R[1..n1+1] be new arrays
int L[n1+1];
int R[n2+1];
for(int i=1; i<n1;i++)
{
L[i]=A[p+(i-1)];
}
for(int j=1; j<n2; j++)
{
R[j] = A[q+j];
}
L[n1+1]=NULL; //sentinel
R[n2+1]=NULL; //sentinel
int i=1;
int j=1;
for (int k=p; k<r; k++)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
}
void MERGESORT(int *A,int p, int r)
{
if (p<r)
{
int q=floor((p+r)/2);
MERGESORT(A,p,q);
MERGESORT(A,q+1,r);
MERGE(A,p,q,r);
}
}
With int L[10]; and my A[10]; my output is:
Sort: 7474 28268 32506 13774 14411
Press any key to continue . . .
If someone could just assist in the two problems, I more than likely will get it to work.
You are failing to detect the end of your merge arrays:
for (int k=p; k<r; k++)
{
// You need to check that i/j are still in range.
// otherwise the following test are not valid.
if ((i < n1) && (j < n2))
{
if(L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
else
{ /* More work here */
}
Other comments:
Identifiers that are all capitol MERGE MERGESORT are generally reserved for macros. If you use them you are likely to hit problems. Prefer function names of mixed case.
You can simulate arrays with vector:
// Simulate L[1..n1+1]
minI = 1;
maxI = n1-1;
std::vector<int> const L(A+(minI-1), A+(maxI-1));
Arrays in C++ are zero indexed. You seem to be having off by one errors (especially in accessing the end of the array). I would advice you to start the count at 0 rather than 1. Most C++ code is written in terms of iterators from [begining..1PastEnd). I think you will find your algorithm easier to implement if you adapt that style.
There are several issues with your code, I've pointed them out in comments. This is a solution closest to your code, and it's far from best. Consider using C++ containers, like std::vector for example. Naming is at least disputable, and of course merge sort should be implemented as an in place algorithm.
//L and R are auxiliary arrays
//preallocated with (inputSize/2 + 1) constant size
void MERGE(int *A, int p, int q, int r, int* L, int* R)
{
if (p > q || q > r)
{
return;
}
int n1 = q - p + 1;
int n2 = r - q;
// note 0-based indices
int i = 0;
int j = 0;
for(;i < n1;i++)
{
L[i] = A[p + i];
}
for(;j < n2;j++)
{
R[j] = A[q + j + 1]; //+1 because p + n1 - 1 == q + 0
}
//again - note 0-based indices
i = 0;
j = 0;
for (int k = p; k <= r; ++k)
{
// The most important fix - in your code you didn't check
// for left/right array bounds at all.
// Sentinel values aren't needed - size is known
if(i < n1 && (j >= n2 || L[i] <= R[j]))
{
A[k] = L[i];
++i;
}
else if (j < n2)
{
A[k] = R[j];
++j;
}
}
}
void MERGESORT(int* A, int p, int r, int* L, int* R)
{
if (p < r)
{
int q = (p + r) / 2; //floor was redundant
MERGESORT(A, p, q, L, R);
MERGESORT(A, q+1, r, L, R);
MERGE(A, p, q, r, L, R);
}
}
void MERGESORT(int* A, int size)
{
int*L = new int[size/2 + 1]; //preallocate auxiliary arrays
int*R = new int[size/2 + 1]; //size/2 + 1 is what will be needed at most
MERGESORT(A, 0, size - 1, L, R);
delete L;
delete R;
}
int main()
{
int A[5]{ 7474, 28268, 32506, 13774, 14411 };
MERGESORT(A, 5);
for (int i = 0;i < 5;++i)
{
std::cout << A[i] << std::endl;
}
return 0;
}
Output:
7474
13774
14411
28268
32506
Credit goes also to DyP for spotting all the mistakes in the previous version :)