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
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.
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";
}
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?
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'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;
}