I was trying to implement this problem from SPOJ: http://www.spoj.com/problems/COINS/ using memoization but I keep getting Runtime error and cant figure out why. Here is my code:
#include<stdio.h>
long long int max(long long int a,long long int b)
{
if(a >= b)
return a;
else
return b;
}
long long int dp[100000];
long long solve(long long int n)
{
long long ans;
if(n<=50000)
return dp[n];
else
ans=(n,solve(n/2)+solve(n/3)+solve(n/4));
return ans;
}
int main()
{
long long int n;
int t;
for(int i = 0;i <=50000;i++)
{
dp[i] = max(i,dp[i/2] + dp[i/3] + dp[i/4]);
}
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
return 0;
}
Here are a few problems:
In solve, you have ans = (n,solve(n/2)...); The leading n has no effect. Did you intend this to be an argument list to max? If so, you need to add max. Otherwise it's just a comma expression and you might as well remove the leading n.
In main, your initialization of dp has a problem. Consider the first pass through the loop, when i is 0. In this case, i/2 etc. will also be zero, hence those dp values will be undefined. Try setting dp[0] explicitly, outside of the loop, and then start your loop at index 1 instead.
When printing the solution in main, you probably want to add newling \n to the end of your printf format string.
As noted by others, when calling solve from main, you are passing n rather than t.
The problem is most likely due to this:
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
You are reading t but passing n which is uninitialized. You probably want to pass t to solve():
while((scanf("%d",&t))>0)
printf("%lld",solve(t));
Reason you get Runtime Error
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
Here, You get input in variable t but pass variable n to solve function. Use variable t or n for both case. It will solve your problem.
Related
I have an array that is made up doubles which I need to round down and convert to integers so I can use them as indices in an output array. I have just started C programming and am not sure how this works. So far the best I have been able to come up with is:
int create_hist( double input_array[], int count, int output_array[17] ) {
for ( int i = 0; i < count; i++ ) {
input_array[i] = int floor(input_array[i]);
output_array[input_array[i]]++;
However I am getting the following errors which I am having trouble deciphering:
array.c:11:20: error: expected expression before ‘int’
input_array[i] = int floor(input_array[i]);
^
array.c:12:7: error: array subscript is not an integer
hist[input_array[i]]++;
^
array.c:14:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
If someone could let me know where I have gone wrong it would be greatly appreciated.
Unless you actually want to modify input_array, you would be best off saving the rounded off double in an intermediate variable to then access your integer array. And no need to use floor() casting the double to int will do that.
int create_hist(double input_array[], int count, int output_array[17]) {
for (int i = 0; i < count; i++) {
int index = (int)input_array[i];
if ((index > 16) || (index < 0)) {
return -1;
}
output_array[index]++;
}
return 0;
}
Of course, you should really pass in the size of output_array as a variable as well, instead of hard-coding it.
So let get cracking:
First error is due to the fact that you are kind of declaring a function.
input_array[i] = int floor(input_array[i]);
notice int in front of floor, that is not necessary. It should be
input_array[i] = floor(input_array[i]);
Second error is due to the fact that you are accessing array element using double in
output_array[input_array[i]]++;
either you should do it some other way or do following:
output_array[(int) input_array[i]]++;
and the third error is unbalanced parenthesizes.
I cannot understand how this code is causing a segfault when I run it, can anyone help me understand what is going on??
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 1ULL) return amt;
else return factorial(x-1ULL, amt*x);
}
int main(int argc, char *argv[])
{
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
First, the segfaults are not necessarily caused be invalid pointer dereference. In this case, it is actually caused by infinite recursion and eventual running out of stack space. Why? The essential requirement of a recursion function is it has to finish and terminate the recursion at some state, if you look carefully your code, in function factorial, if x is 0, then the recursion will become endless and eventually crash your program. You can fix this by change the terminate condition to:
if (x <= 1ULL) return amt;
In the orginal code :
if (x == 1ULL) return amt;
is meant to be the exit condition for this recursive function factorial. However when a value of zero is passed to the function and given that the type of x is unsigned long long, first recursive call to the function factorial with the parameter x-1ULL would set the value of x to very large value (18446744073709551615 is what I got here). Successive recursive calls to factorial will gradually deplete the stack space allocated for the program to the point where you get a segmentation fault.
You should have been doing this:
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 0ULL) // Changed the exit condition, see Reference [1]
return amt; // Bear in mind that the initial value for amt you passed is 1
amt*=x; // See Reference [2]
return factorial(x-1ULL, amt);
}
int main(int argc, char *argv[]) {
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
References
The idea of the factorial (in simple terms) is used to compute the number of permutations (combinations) of arranging a set of n numbers. It can be said that an empty set can only be ordered one way, so 0! = 1. Check this.
I feel this is more readable than factorial(x-1ULL, amt*x)
Note
The ULL suffixes are redundant here and may be removed altogether.
I am doing a simple function that returns the minimum integer from numbers given from the user(array).
However, it always print 2686916 at the end. Here is my code:
int function()
{
int ar[100];
int i;
int smallest = INT_MAX;
int nums;
int num;
int sum=0;
printf("\nenter array size\n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
if (nums <smallest){
smallest=nums;
printf("the smallest %d\n,smallest);
return 0;
}
}
I'm not sure what I'm doing wrong.
My friend, it seems you are new to C, and before you ask questions like this one you should try to follow some tutorials for C. You might try something like this.
If the question you ask is not clear or the code you post won't compile anyway it is very hard to help you out. For now this is all I can do:
int function()
{
int ar[100];
int i;
int smallest = INT_MAX;
int nums = 0; //Always Initialize your variables!
int num = 0;
int sum= 0;
printf("\nenter array size\n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
if (nums <smallest)
{
smallest=nums;
printf("the smallest %d\n",smallest);
}
return 0; //Don't put this in a place that might not be executed!
}
Now it should at least compile, it still doesn't do anything useful as far as I can see. You compare "nums", a variable you didn't use before, with the biggest value of an int, set it to the never used "nums" and print it.
You might want use "sums" or "ar[i]" in the if statement instead, and printing one of these values.(still not 100% sure what you want to do).
Some tips for next time (before you ask a question!):
Variables should always be initialized
In your code you try to use the value of "nums" before it gets a value, this might cause errors or strange results in your code.
Don't put a return in a place that might be skipped,
In your code, "nums" would be bigger than "smallest" (unlikely, bit for example), the code would skip the if statement and never reach the return.
Read your compiler warnings
The code you posted can't compile, read your errors and warnings, and fix them.
(tip) Use better variable names, using names like nums, num and sum make it easy to overlook a mistake.
I've very recently started to learn C, so I realize my question is very basic, but any help would be very much appreciated.
I'm trying to get the function fact to return the res value to main, but when I print out the result in main I just get 0. By inserting some print statements I can see that res is calculating correctly in the fact routine but the result is not returning correctly to main.
I'm sure I'm missing something very basic here.
Thanks
#include <stdio.h>
unsigned long fact (int n){
unsigned long res = 1;
while ( n >= 0 )
{
res *= n;
n--;
}
return res;
}
int main (void){
int n;
unsigned long res;
printf("Insert number:\n");
scanf("%d", &n );
res = fact (n);
printf("The factorial number is %lu", res);
return 0;
}
Your loop condition is n >= 0, which means that res will be multipled by 0 before the function returns. Thus the result will always be 0.
You loop condition is wrong. The last run of while (n>=0) will have n=0. Multiplying res by this will reset it to 0.
You can fix this by changing your loop to while (n > 1)
For future reference, you could investigate problems like this using a debugger (e.g. GDB or visual studio express). Or by adding printf statements to your code to trace the flow and see how the value of res changed through the program.
What em trying to do is pass the array to a function which will add all the array elements and return the output. Please help me. i dont know what i am doing wrong in this :/
#include <stdio.h>
#define MAX 5
int arraySum(int *dArr,int lim);
int main()
{
int array[MAX] = {9,7,4,2,10};
printf("%d", arraySum(array, MAX));
return 0;
}
int arraySum(int *dArr,int lim)
{
int Ans;
if(lim>0)
Ans = dArr[lim] + arraySum(*dArr, lim--);
return Ans;
}
There are several problems with your code:
You're accessing array[MAX], which is undefined behaviour.
Your function returns the uninitialized Ans when lim is zero.
The first argument to arraySum in the recursive call is wrong.
The use of lim-- is wrong.
Since this looks like homework, I'll let you figure out how to fix these problems. If this isn't homework, you might want to consider whether recursion is the right tool for the job.
You run into undefined behavior on dArr[lim], because lim is 5 and the array has elements 0...4.
You also get undefined behavior when lim==0, because you return an un-initialized Ans. When you declare it, initialize it to dArr[0].
After you fix this, you'll want to pass dArr itself further in the recursion, as dArr only returns an int.
Remember that computers treat 0 as the first number, so your array will number from element[0] to element[4]. your code starts from five and counts down to one, which means elements[5] in this case will return garbage, because the index does not exist. pass Lim - 1 into the function or manually changed the value in your function.
ArraySum(Array, MAX - 1);
OR
ArraySum(//....)
{
lim--;
//code here....
}
EDIT: you also need to initialize ans to some value, so if an array of zero elements is passed the function wont return an uninitialized variable.
int arraySum(int *dArr,int lim)
{
int Ans;
if(lim>=0) // note the change here
Ans = dArr[lim] + arraySum(dArr, --lim); // note the --lim change here
return Ans;
}
You should invoke this with lim as 4 and not 5. Because the array has 5 integers starting from index 0 to index 4. 5th index is out of bounds.
--lim instead of lim-- because lim-- is post decrement. That means the value is first passed and then decremented. Hence everytime your arraySum function gets the value as 4 instead of 3, 2, 1 and 0 (as per your expectation). --lim is pre-decrement.
Change MAX to 4 and change the if(lim>0) condition as if(lim>=0)
This will make your recursion to add as dArr[4]+dArr[3]+dArr[2]+dArr[1]+dArr[0] i.e. all 5 elements of the array.
EDIT: Corrected program:
int main()
{
int array[MAX] = {9,7,4,2,10};
printf("%d", arraySum(array, MAX-1));
return 0;
}
int Ans = 0;
int arraySum(int *dArr,int lim)
{
if(lim>=0){
Ans = dArr[lim] + arraySum(dArr, lim-1);
}
return Ans;
}