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.
Related
The general problem:
Given an array of integers nums and an integer k. A continuous subarray is called nice if there are k odd numbers on it.
Return the number of nice sub-arrays.
My question:
I want to solve this problem recursively. The part I'm struggling to implement is how do I use the count from every previous recursive call and sum up all the counts, and return one last count like it is shown in the attempt.
Example:
Input: nums = [1,1,2,1,1], k = 3
Output: 2
Explanation: The only sub-arrays with 3 odd numbers are [1,1,2,1] and [1,2,1,1].
My attempt:
int helperFunction(vector<int> &nums, int k, int starter, int count)
{
int sum=0;
if (starter >= nums.size())
{
return count;
}
for (int i = starter; i < nums.size(); i++)
{
if (nums[i] % 2 == 1)
{
if (++sum == k)
{
count += nums.size() - i;
sum = 0;
}
}
}
return helperFunction(nums, k, starter + 1, count);
}
int numberOfSubarrays(vector<int> &nums, int k)
{
return helperFunction(nums, k, 0, 0);
}
int main()
{
vector<int> mine;
int myints[] = {1, 1, 2, 1, 1};
mine.assign(myints, myints + 5);
cout << "Output : " << numberOfSubarrays(mine, 3);
return 0;
}
Return Value:
The return value of this actual attempt is 0 means the program is at least not wrong syntactically.
it's not particularly good candidate for recursion. might be possible to solve with just one pass on the array.
That said, small adjustments to your code could make it work. There is no reason to pass count into the recursive method.
Your method calculates the number of subarrays that are 'nice' starting with the given index. Add that to the number that start at the next index and return it.
int helperFunction(vector<int> &nums, int k, int starter)
{
int sum=0, count=0;
if (starter >= nums.size())
{
return 0;
}
for (int i = starter; i < nums.size() && sum <= k; i++)
{
if (nums[i] % 2 == 1)
{
sum++;
}
if (sum == k)
{
count++;
}
}
return helperFunction(nums, k, starter + 1) + count;
}
I'm not sure your counting was correct. This could be optimized a lot, but this should demostrate the recursive approach.
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";
}
It is a very simple code that should solve the Cut Rod Optimization Problem. Most of the time it outputs the correct output but sometimes it gives random answers. I don't know what might be causing this.
Code:
#include <iostream>
#include <limits>
int cutRod(int p[], int n);
int max(int a, int b);
int main()
{
int n = 10;
int p[n] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
int numOfCuts = cutRod(p, n);
std::cout << "Cuts: " << numOfCuts << std::endl;
return 0;
}
int cutRod(int p[], int n)
{
if (n == 0)
{
return 0;
}
int q = INT32_MIN;
for (int i = 0; i <= n; ++i)
{
q = max(q, p[i] + cutRod(p, n-i-1));
}
return q;
}
int max(int a, int b){
if (a >= b)
{
return a;
}
else if (b > a)
{
return b;
}
}
How to regenerate error:
Just run the program a couple of times. Most of the times, it gives 30 as answer. Which is correct. But other times, it will give a random big number as an output.
for (int i = 0; i <= n; ++i)
{
q = max(q, p[i] + cutRod(p, n-i-1));
}
here you are calling p[n] which is out of index but in c++ array it still lets you access that memory block having a garbage value, so you are basically adding a garbage value with returned value of function.
in array you will have valid value upto only 0 to n - 1 for p,
I guess this is the thing that is causing the problem
This is a question from hackerrank; I am trying to understand how recursion works.
The task at hand is:
Find the number of ways that a given integer, X, can be expressed
as the sum of the Nth power of unique, natural numbers.
So for example, if X = 100 and N = 2
100 = 10² = 6² + 8² = 1² + 3² + 4² + 5² + 7²
so 100 can be expressed as the square of unique natural numbers in 3
different ways, so our output is 3.
Here is my code,:
#include <cmath>
#include <iostream>
using namespace std;
int numOfSums(int x, int& n, const int k) {
int count = 0, j;
for (int i = (k + 1); (j = (int) pow(i, n)) <= x; i++) {
j = x - j;
if (j == 0)
count++;
else
count += numOfSums(j, n, i);
}
return count;
}
int main() {
int x, n;
cin >> x >> n;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
But when I input x = 100 and n = 2, it's outputting 2, not 3. What's wrong with the code?
Link to the question: https://www.hackerrank.com/challenges/the-power-sum
Your example code returns 3 when I run it using this main():
#include <iostream>
int main() {
int x = 100, n = 2;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
The problem is likely that you're using double std::pow(double, int), but you're not rounding the result to nearest integer ((int) casts round down). You should add ½ before truncating:
j = static_cast<int>(pow(i, n) + 0.5)
I've used the more-C++ style of cast, which I find clearer.
It would be more efficient to implement your own equivalent of std::pow() that operates on integers. That can be recursive, too, if you want:
unsigned long pow(unsigned long x, unsigned long n)
{
return n ? x * pow(x, n-1) : 1;
}
An iterative version is more efficient (or a tail-recursive version and suitable optimizing compiler).
Reduced version, with my changes:
template<typename T>
T powi(T x, T n)
{
T r{1};
for (; n; n /= 2) {
r *= n%2 ? x : 1;
x *= x;
}
return r;
}
template<typename T>
T numOfSums(T x, T n, T i = {})
{
T count{}, j;
for (++i; (j = powi(i, n)) <= x; ++i)
count += j == x ? 1 : numOfSums(x-j, n, i);
return count;
}
#include <iostream>
int main()
{
unsigned long int x = 100, n = 2;
std::cout << numOfSums(x, n) << std::endl;
return 0;
}
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;
}