Matrix Chain Multiplication using Dynamic Programming in C++ Program Crashes? - c++

I have written following C++ program to implement to implement MCM using Dynamic Programming. But the following program crashes. What is wrong in my code ?
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {2,3,3,5};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<=j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i-1]*P[j]*P[k];
if(sum<min)
min = sum;
}
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(0,size-1));
return 0;
}

Your code is going to infinite loop. Besides you have made some mistakes:
You have never assigned the optimum value in the table (when you find minimum sum, you are not storing it). Hence every time you are checking for table[i][j] == 0, it's true
k in your loop can be equal to j and you are using k+1, this is a mistake
Anyway I think the right version of your code should be something like this:
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {1,2,3,4};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i]*P[j]*P[k];
if(sum<min)
min = sum;
}
table[i][j] = min;
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(0,size-1));
return 0;
}

The first time MCM(0, size-1) is called, the parameter i = 0, but then you subtract 1 and use the resulting -1 to access P[-1] (on line 23). That probably causes the crash.

Oh I got what is wrong with this its just a minor mistake
The loop on should on line 17 should end at the condition
k<j
and not at
k<=j
The program compiles and runs successfully
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {1, 2, 3, 4, 3};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<j;k++) // bug was here: for(int k=i;k<=j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i-1]*P[j]*P[k];
if(sum<min)
min = sum;
}
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(1,size-1));
return 0;
}

Related

Segmentation fault in recursive program

I am doing the coin problem, the problem says that,
Given a set of coin values coins = {c1, c2,..., ck} and a target sum
of money n, our task is to form the sum n using as few coins as
possible.
suppose you have 9 dollars and you have set of {6,5,1} so, the minimum no. of sum/change for 9 dollars would be ( 6+1+1+1=9) i.e. 4.
i tried doing it recursively using this formula :
solve(x) = min( solve(x−6)+1, solve(x−5)+1, solve(x−1)+1 )
,but I don't know why I'm getting Segmentation fault in my code.
There are plenty of codes available online, but I want to know what am I doing wrong here, I'm new to recursion please help me, The code goes here:
//my code
#include<bits/stdc++.h>
using namespace std;
int solve (int x, int a[], int n)
{
if (x < 0)
{
return INT_MAX;
}
if (x == 0)
{
return 0;
}
int best = INT_MAX;
for (int i = 0; i < n; i++)
{
best = min (best, solve (x - a[i], a, n) + 1);
}
return best;
}
int main ()
{
int a[] = { 6, 5, 1 };
int x = 9;
int n = 3;
cout << solve (x, a, n);
return 0;
}
The code which have been took from: https://www.geeksforgeeks.org/find-minimum-number-of-coins-that-make-a-change/
#include <iostream>
using namespace std;
int minCoins(int coins[], int m, int amount) {
if (amount == 0) return 0;
int res = INT_MAX;
for (int i = 0; i < m; i++) {
if (coins[i] <= amount) {
int sub_res = minCoins(coins, m, amount - coins[i]);
if (sub_res != INT_MAX && sub_res + 1 < res) { // avoid overflow
res = sub_res + 1;
}
}
}
return res;
}
int main() {
int coins[] = { 6, 5, 1 };
int amount = 9;
cout << "Min coins is "
<< minCoins(coins, sizeof(coins) / sizeof(coins[0]), amount)
<< endl;
return 0;
}
About the problem:
Your Segmentation fault comes from the line:
best = min (best, solve (x - i, a, n) + 1);
The reason is: x-i will always gives you the same value so if you are run the program without debugging, your program crashing. So don't try to debug it because it will takes a lot of time to see this crashing.
For starters change to: best = min (best, solve (x - a[i], a, n) + 1);.
After fixing the section 1, the if case: if (x < 0) return INT_MAX; will causes problem and will return always the same value, which is: -INT_MAX. So you need to check the "if cases" again.
The algorithm you try to implement is not correct, see the pseudo-code of this algorithm:
minchange(M):
if M = 0:
return 0
v <- infinity
for c in denominations <= M:
v <- min { minchange(M - c) + 1, v }
return v
Better use: sizeof(a) / sizeof(a[0]) instead of int n = 3.

How to write combinations recursively in C++

I wrote a program for finding combination(n Choose r = nCr) using for loop/iterations, wanted to know how to do the same using recursion.
Code is as follows:
#include<iostream>
using namespace std;
int main(){
int n,r;
float num = 1,denum = 1,comb = 1;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
for (int i = 1; i <= r; i++)
{
num *= (n-r+i);
}
for (int i = 1; i <= r; i++)
{
denum *= (i);
}
comb = num/denum;
cout<<"The number of combinations is "<<comb<<"\n";
}
The following code that I've written helps in finding nCr through recursion:
#include<iostream>
using namespace std;
float comb(int n,int r){
if(r!=0)
{
return (n-r+1)*comb(n,r-1)/r;
}
else
{
return 1;
}
}
int main(){
int n,r;
float com;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
if(n-r>=r)
{
com = comb(n,r);
}
else
{
com = comb(n,n-r);
}
cout<<"The number of combinations is "<<com<<"\n";
}
Had done this program recently, upon calling the com function in main(), the function is calling itself(i.e recurses) until r value becomes 0 after which it goes to the base statement i.e return 1 if r equals 0
If you just need a code, here it is
int findNumerator(int num, int i, int r) {
return num * (i != r ? findNumerator(num, i+1, r) : 1);
}
int findDenominator(int denum, int i, int r) {
return denum * (i != r ? findDenominator(denum, i+1, r) : 1);
}
int main(){
int n,r;
float num = 1,denum = 1,comb = 1;
cout<<"Enter the values of n and r in nCr \n";
cin>>n>>r;
comb = findNumerator(num, 1, r) / findDenominator(denum, 1, r);
cout<<"The number of combinations is "<<comb<<"\n";
}

How to print only the unordered elements?

I am working on a code to print all the numbers which have their LCM as 240. Now this is pretty easy, write 2 for loops and you're done. I have provided the code below. What I want now is to remove duplicate pairs. For example, if I have already printed (16,30) I dont want to print (30,16).
So what I have thought to resolve this is modify the 2nd indices to have an upper limit equal to the 1st index.
using namespace std;
int findLCM(int a, int b)
{
int lar = max(a, b);
int small = min(a, b);
for (int i = lar; ; i += lar) {
if (i % small == 0)
return i;
}
}
int main()
{
int a = 5, b = 7,s=0;
for(int i=1;i<=360;i++){
for(int j=1;j<=i;j++){
if(findLCM(i,j)==360){
cout<<"("<<i<<","<<j<<")"<<endl;
s++;
}
}
}
cout<<s;
return 0;
}
\\modified code
using namespace std;
{
int lar = max(a, b);
int small = min(a, b);
for (int i = lar; ; i += lar) {
if (i % small == 0)
return i;
}
}
int main()
{
int a = 5, b = 7,s=0;
for(int i=1;i<=240;i++){
for(int j=1;j<=i;j++){
if(findLCM(i,j)==240){
cout<<"("<<i<<","<<j<<")"<<endl;
s++;
}
}
}
cout<<s;
return 0;
}
So I found that this does seem to work. Is this modification in the loop enough to ensure that duplicate pairs aren't printed?

finding sum of numbers in a char array

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.

C++ implementation of Kruskal's algorithm

I'm trying to implement Kruskal's algorithm. Here is a map of the structures I'm using:
g = array of edges, it keeps the left end and the right end and the edge's weight;
c = array which memorises the conex components; c[N] = the conex component in which we find the Nth vertex;
a = array which memorises the MST;
m = nr of vertexes;
n = nr of nodes.
There are two problems with the following code:
1) For the following input it outputs that the cost of the MST is 18 (which is wrong, the cost is actually 14):
7 ( =m )
6 ( =n )
1 2 9
1 3 5
1 4 2
2 3 7
3 5 3
4 6 1
5 6 1
2) Compiling the code step by step doesn't give any errors, although the actual execution of the program halts at some point, I figure it's when printing the cost of the MST.
Thanks for helping! Here's the code:
#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101
FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");
struct Vertex{
int first,last,Cost;
};
void read_graf(Vertex **g, int *c, int &m, int &n){
int x,y,w;
fscanf(fin,"%d%d",&m,&n);
*g = (Vertex *)malloc(m*sizeof(Vertex));
for(int i=1;i<=m;++i){
fscanf(fin,"%d%d%d",&x,&y,&w);
(*g+i)->first = x;
(*g+i)->last = y;
(*g+i)->Cost = w;
}
for(int i=1;i<=n;++i)
c[i] = i;
}
int costMST(Vertex *g, int *a, int n){
int MST = 0;
for(int i=1;i<n;++i)
MST += g[a[i]].Cost;
return MST;
}
void Kruskal(Vertex *g, int *c, int *a, int n){
int nr = 0, mini, maxi;
for(int i=1;nr<n-1;++i)
if(c[g[i].first] != c[g[i].last]){
a[++nr] = i;
if(c[g[i].first] < c[g[i].last]){
mini = c[g[i].first];
maxi = c[g[i].last];
}
else{
maxi = c[g[i].first];
mini = c[g[i].last];
}
for(int j=1;j<=n;++j)
if(c[j] == maxi)
c[j] = mini;
}
}
inline int cmp(const void *a, const void *b){
return (((Vertex *)a)->Cost - ((Vertex *)b)->Cost);
}
int a[grafMAX], c[grafMAX];
int main(){
Vertex *g;
int m, n;
read_graf(&g,c,m,n);
qsort(g,m,sizeof(Vertex),cmp);
Kruskal(g,c,a,n);
fprintf(fout,"The cost of the MST is: %d.\n",costMST(g,a,n));
fclose(fin);
fclose(fout);
return 0;
}
There are a lot of off by one errors in your code, I think because you are numbering your vertices from 1 rather than 0. One of these errors was causing it to crash, and I think another one was causing the wrong result to be produced.
I changed all of the internal numbering to be 0-based and and that has got it to work. I renamed your variables because they were quite preposterously named (what you call a Vertex is an Edge) and I couldn't make sense of the code with them like that.
I'm afraid I lost track of everything I changed, but I expect you can see what I did if you compare it with your original code.
Notice that I added some debug lines. When you can't work out what your code is doing, just print the relevant variables and you will soon see what the problem is.
#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101
FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");
struct Edge {
int first,last,Cost;
};
void read_graf(Edge **g, int *components, int &num_edges, int &num_vertices){
int x,y,w;
fscanf(fin,"%d %d",&num_edges,&num_vertices);
*g = (Edge *)malloc(num_edges*sizeof(Edge));
for(int i=0;i<num_edges;++i){
fscanf(fin,"%d %d %d",&x,&y,&w);
(*g+i)->first = x - 1;
(*g+i)->last = y - 1;
(*g+i)->Cost = w;
}
for(int i=0;i< num_vertices;++i)
components[i] = i;
}
int costMST(Edge *edges, int *answer, int num_edges){
int MST = 0;
for(int i=0;i<num_edges;++i)
MST += edges[answer[i]].Cost;
return MST;
}
void print_components(const int* components, int num_components)
{
for (int i = 0; i < num_components; i++) {
printf("Vertex %d is in component %d\n", i, components[i]);
}
putchar('\n');
}
void print_edge(const Edge& edge, int index)
{
printf("Edge %d connecting %d to %d with weight %d", index, edge.first, edge.last, edge.Cost);
}
void Kruskal(Edge *edges, int *components, int *answer, int num_edges, int num_vertices){
int nr = 0, mini, maxi;
for(int i=0;i<num_edges && nr < num_vertices - 1;++i) {
printf("Considering ");
print_edge(edges[i], i);
putchar('\n');
if(components[edges[i].first] != components[edges[i].last]){
printf("Adding ");
print_edge(edges[i], i);
putchar('\n');
answer[nr++] = i;
if(components[edges[i].first] < components[edges[i].last]){
mini = components[edges[i].first];
maxi = components[edges[i].last];
}
else{
maxi = components[edges[i].first];
mini = components[edges[i].last];
}
for(int j=0;j<num_vertices;++j)
if(components[j] == maxi)
components[j] = mini;
print_components(components, num_vertices);
}
else {
printf("Rejecting ");
print_edge(edges[i], i);
putchar('\n');
}
}
}
inline int cmp(const void *a, const void *b){
return (((Edge *)a)->Cost - ((Edge *)b)->Cost);
}
int answer[grafMAX], components[grafMAX];
int main(){
Edge *edges;
int num_edges, num_vertices;
read_graf(&edges,components,num_edges,num_vertices);
qsort(edges,num_edges,sizeof(Edge),cmp);
Kruskal(edges,components,answer,num_edges,num_vertices);
fprintf(fout,"The cost of the MST is: %d.\n",costMST(edges,answer,num_vertices - 1));
fclose(fin);
fclose(fout);
return 0;
}