I am new to coding. so I wanted to write a c program using recursion to calculate the factorial of a number.
#include <stdio.h>
int fact(int a) {
int n = 1;
if (a != 0)
return;
else
n = n * a;
a--;
fact(a);
return n;
}
int main() {
printf("%d", fact(5));
return 0;
}
This is the program I have written. I know this is probably wrong but I think I would understand programming better if I was able to understand why the above program is exactly wrong.
Because whenever you pass any value other than 0 to fact your code exits without even returning a value:
if(a!=0)
return;
You should get at least a warning from your compiler that this is invalid code, since fact is expected to always return an int value.
But even more so, this is a logical error.
Did you mean to write:
if (a == 0) return 1; //0! = 1
Lev M. pointed out your mistakes in his answer. This is a working recursive implementation of the factorial algorithm.
unsigned int fac(unsigned char n)
{
if (n == 0)
return 1;
return n * fac(n - 1);
}
Related
This is a recursive function to find the amount of 2 appearing in a number.
Example Input:
221122
Example Output:
countTwo(): 4
#include <stdio.h>
void countTwo2(int num, int *result);
int main()
{
int number, result;
printf("Enter the number: \n");
scanf("%d", &number);
countTwo2(number, &result);
printf("countTwo2(): %d\n", result);
return 0;
}
void countTwo2(int num, int *result)
{
if(num > 0) {
if((num % 10)/2 == 1) {
*result += 1;
}
countTwo2(num/10, result);
}
}
I can't increment result since it has not been initialised but I also can't initialise result in the recursive function as this will reset the result.
Edit: This is a question given, with all the template written as above except for the code within countTwo. We are supposed to write the code in countTwo such that main() will be able to run.
Edit2: Thanks for the help! This problem has been solved by using static int. I understand that this is not very efficient. I will also ask my teacher pertaining to this question. Once again, Thanks!
The way to keep all the oddities of this code:
it has to be recursive
you cannot change main, so the initial result value will be undefined
is to, as you stated you cannot do, actually reset result inside countTwo2. However, you need to it in the right place, before you start incrementing.
The way to do that is to reorder your function and add the part that resets the value at the right place:
void countTwo2(int num, int* result)
{
if (num > 0)
{
countTwo2(num / 10, result);
if ((num % 10) / 2 == 1)
{
*result += 1;
}
}
else
*result = 0;
}
Notice that I moved the recursive call up above the if-then block that increments the result, and that when num is 0, we reset. This will call recursively down digits of the input until we're at the end, then reset the result, then return back up one digit at a time and optionally increment the value.
This requires no other changes to your code.
As many have stated, in comments and answers, this is obviously not a good implementation or design but if you have a confined context to work in, this is probably as good as it gets.
I can't see any good reason for declaring this as a void function with the result passed back via pointer parameter.
The following would be a lot cleaner, surely?
int countTwo(int num) {
return (num == 0) ? 0 : (num % 10 == 2) + countTwo(num / 10);
}
For reference, the proper way to write such a function is to not use recursion. It isn't obvious that the compiler will be able to unroll the recursion in this case, as the recursive call would be in the middle of the function, and also conditional.
Thus the only thing gained from recursion is slow execution and higher stack peak use. Why would we want slow execution when we can have fast execution? You should ask your teacher this question, so they can tell you why they are teaching it. I would be most curious to hear their rationale.
For a professional, non-academic programmer, the proper way to write the function would be to use a loop:
int count_n (int input, int n)
{
int result = 0;
for(; input>0; input/=10)
{
if(input%10 == n)
{
result++;
}
}
return result;
}
(This version doesn't work with negative numbers.)
As I mentioned before you may use static variables.
You do not need two arguments.
Here is a solution: #Lasse Vågsæther Karlsen
#include <stdio.h>
int countTwo2(long int num)
{
static int m=0; //static variable is initialized only once.
if (num==0)
return m;
else if (num % 10 ==2)
m=m+1;
num=num /10;
countTwo2(num);
}
int main()
{
int result; long int number;
printf("Enter the number: \n");
scanf("%ld", &number);
result=countTwo2(number);
printf("countTwo2(): %d\n", result);
return 0;
}
I would like to solve problem PRIME1 on SPOJ. When I run Code Blocks and input test examples, I get correct answer. But when I submit my code to SPOj, I get SIGSEGV error. Here is the explanation of this error on SPOJ:
SIGSEGV (signal 11) - the most common error for non-interpreted languages: a "segmentation fault" of the program. This may be caused e.g. by an out-of-scope array index causing a buffer overflow, an incorrectly initialized pointer, etc.
But I can't find this type of problem in my code. Could anyone help me, please?
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
int prim(int n)
{
int s, i;
if (n == 1 || n == 2)
return 1;
if (n % 2 == 0)
return 0;
s = (int)sqrt(n);
for (i=3; i<=s; i+=2)
if (n % i == 0)
return 0;
return 1;
}
void print(int a,int b)
{
int *p,i,k;
int g;
g=(b/2);
p = (int *) malloc (sizeof(int)*(b-a+1));
for(i=0;i<(b-a+1);i++) p[i]=a+i;
for(i=0;i<=g;i++)
{
if(p[i] && prim(p[i]))
{
for(k=i*2+a;k<b-a;k+=i+a)
p[k]=0;
}
if(!prim(p[i]))
{
p[i]=0;
for(k=i*2+a;k<=b-a;k+=i+a)
p[k]=0;
}
}
for(i=0;i<(b-a+1);i++) if(p[i]!=0) printf("%d ",p[i]);
free(p);
}
int main(void)
{
int t,i,m,n;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d %d",&m,&n);
print(m,n);
}
return 0;
}
The problem is that g maybe greater than or equal to (b-a+1), depending on the test case. Since g = b/2 then for the array index i to not go out of bounds, b/2 < b-a+1 which implies that b/2 > a-1. That is not necessary. Since a can be say 6 and b can be like 7 according to the problem constraints.
Also according to the constraints, your code might well give TLE. Your algorithm is currently in the worst case O((n-m)*sqrt(n)), which I think is not enough to get AC in this question.
Read about Sieve of Eratosthenes and try to use it to solve this.
I need to implement this math formula in C:
I wrote a code:
#include <stdio.h>
int c(int n, int k)
{
if(k == 0)
return n;
if(c(n,k-1) % 2 == 0)
return c(n,k-1)/2;
if(c(n,k-1) % 2 != 0)
return c(n,k-1) * 3 + 1;
}
int main()
{
printf("%d", c(3,8));
return 0;
}
But I'm wondering if it was all about it? Does it work like it should? I must admit I have some troubles with calculating it on a paper ...
According to my calculation, the correct answer for n=3, k=8 should be 4, so your example should give you that. The program itself looks correct.
Update:
Here is how I do it on paper:
We're starting from c(0) - since in this case the value is known in any case:
c(0)=n=3
And go up, on each step choosing the calculation method based on evenness of the c(k-1):
c(1)=c(0)*3+1=10
c(2)=c(1)/2=5
c(3)=c(2)*3+1=16
c(4)=c(3)/2=8
c(5)=c(4)/2=4
c(6)=c(5)/2=2
c(7)=c(6)/2=1
c(8)=c(7)*3+1=4
I am learning C, so I am writting some little exercises in C to practice the language.
I have experience with functional code, so I love recursion. I think that it would be great to achieve tail recursion using C static variables, so additional arguments or helper functions would not be required.
This code to calculate a factorial using recursion, fails:
long long int fact(int n)
{
static long long int result = -1;
if(n <= 0) {
if(result < 0)
return 1;
else {
long long int temp = result;
result = -1;
return temp;
}
} else {
result *= n;
fact(n - 1);
}
}
However, for some reason, I cannot do this in C. Is there an idiom to the same that? Is it just my compiler? What about memoization?
Thanks a lot.
Your code is broken since it has a control path where it doesn't return a value. This works fine:
long long int fact(int n)
{
static long long int result = 1;
if(n <= 1) {
long long int temp = result;
result = 1;
return temp;
} else {
result *= n;
return fact(n - 1);
}
}
GCC does successfully transform the tail recursion to iteration.
In general, I think the reason to avoid using statics for tail recursion is simply because the function loses reentrancy. So much code ends up having to run in a multithreaded environment these days that it's hard to justify leaving function-local static "landmines" in code. I do admit this is as much opinion as technical argument. The non-static tail recursive code:
static inline long long int fact_(int n, long long int result)
{
if(n <= 1) {
return result;
} else {
return fact_(n - 1, result * n);
}
}
long long int fact(int n)
{
return fact_(n, 1);
}
is if anything a bit easier to write - notably both versions are exactly 13 LOC - and compiles just as efficiently to iteration but without needing static data.
You don't seem to have an explicit return value from your else block. Are you not getting compiler warnings on that? Please make sure you're compiling with all warnings turned on.
Basically, you need to add return result; to the end of your else block otherwise how are you going to return the result back to the original caller? Remember, return only pops one function call, and you're an arbitrary depth when you call return because of all the recursive calls to fact() you've made in your else block.
int factorial(int n)
{
static int m = 1;
m *= n;
if (n > 1)
factorial(n - 1);
return m;
}
im trying to solve this very first challange but i get stuck,
i like fast program, so i decided to use recursive method not iteration
unfortunately, when the input is a big integer (100000 > input > 1000000), its often crash
so i debug it, and it shows stack overflow error
please help me, i dont know what to do, ive tried to change data type to unsigned long, unsigned int, etc, but none of it works
here is my code,
im using ANSI C
#include "stdio.h"
int cek(int n) {
return n % 2;
}
int fung(int n,int c) {
if (n == 1) {
return c;
}
if (!cek(n)) {
return fung(n/2,++c);
}
else {
return fung((n*3)+1,++c);
}
}
int comp(int i,int j,int tmp) {
int temp;
if (i == j)
return tmp;
temp = fung(i,1);
if (temp > tmp)
return comp(++i,j,temp);
else
return comp(++i,j,tmp);
}
int main() {
int i,j,tmp;
while (scanf("%d %d",&i,&j)) {
if (i > j) {
tmp = i;
i = j;
j = tmp;
}
printf("%d %d %d\n",i,j,comp(i,j,0));
}
return 0;
}
PS: sorry for my stupidness, im really a newbie #_#
Recursion is not likely to be faster than iteration, and in fact it's likely to be slower.
The call stack has a limited size, and if your recursion goes deeper than that, there's nothing you can do about it. Especially in the Collatz problem, there's no way to tell up front how many steps you'll need. Rewrite this using an iterative method instead.
(If your compiler does tail call optimization, recursion might still work. But TCO is not required by the standard, so it will lead to unportable code. And apparently, your compiler does not optimize this particular tail call anyway.)
Not a C expert, but usually there is a call stack depth limit enforced by the compiler. Probably you can change this with a compiler flag, but this will not solve your problem. Making the algorithm iterative instead of recursive will fix it.
Recursive algorithms won't go faster than iterative ones, usually. But they are typically nicer to understand. (= more elegant)
Okay guys,
i found it!!!
so this is my code, i still use recursion but only for the inner loop fung(),
im not really impressed of it, because its need 0,5 sec to count input 1 and 1000000, someone's code outhere can do it in 0 sec, LOL
i change the outer loop comp() with iterative method,
look here
#include "stdio.h"
/*#include "windows.h"*/
int cek(int n) {
return n % 2;
}
unsigned int fung(unsigned int n,unsigned int c) {
if (n == 1) return c;
if (!cek(n)) return fung(n/2,++c);
else return fung((n*3)+1,++c);
}
/*
Above recursion will looked like this in iterative method
int func(int n) {
int c=1;
while (n != 1) {
c++;
if (n % 2 == 0)
n=n/2;
else
n=(n*3)+1;
}
return c;
}
*/
/*Outer Loop*/
int iter(int i,int j) {
int tmp1=0,tmp2;
while (i <= j) {
tmp2 = fung(i,1);
if (tmp1 < tmp2)
tmp1 = tmp2;
i++;
}
return tmp1;
}
int main() {
unsigned int i,j,s,f;
while (scanf("%d %d",&i,&j)) { /*UVa Standard, infinite loop*/
/*s = GetTickCount();*/
printf("%d %d %d",i,j,iter(i,j));
/*f = GetTickCount();
printf("%lu\n",f-s);*/
}
return 0;
}