I am trying to implement caching based Fibonacci sequence. But it gave me the wrong output for example (fibcache(8) gave me an answer of 13 instead of 21. However in some cases it gave me the correct output. For example fibcache(6) gave me 8. Cant figure out whats wrong
#include <stdio.h>
#include <stdlib.h>
#define DCACHE_SIZE 5
int fibcache(int number);
long cacheodd[DCACHE_SIZE] = {0};
long cacheeven[DCACHE_SIZE] = {0};
int i_odd, i_even;
int main(int argc, char *argv[])
{
int fibNum = fibcache(6);
printf("The Fibonacci number is %d\n", fibcache(fibNum));
}
int fibcache(int n)
{
int result;
if (n == 0)
return 0;
if (n == 1)
return 1;
if(n%2==0)
{
if (cacheodd[i_odd] != 0)
result = cacheodd[i_odd];
else
{
cacheodd[i_odd] = fibcache(n-1) + fibcache(n-2);
result = cacheodd[i_odd];
}
}
else
if(n%2==1)
{
if (cacheeven[i_even] != 0)
result = cacheeven[i_even];
else
{
cacheeven[i_even] = fibcache(n-1) + fibcache(n-2);
result = cacheeven[i_even];
}
}
return result;
}
You have some problems:
You actually print fib(fib(6)), a much larger number than fib(6).
Your caching function is too complicated: why handle even and odd numbers differently? You should make a special case of numbers larger than the cache size and verify if the cached value has been computed.
Here is a simpler version:
#include <stdio.h>
#define DCACHE_SIZE 5
long fibcache(int number);
long fibcache_values[DCACHE_SIZE] = { 0 };
int main(void) {
printf("List of Fibonacci numbers:\n");
for (int i = 0; i < 47; i++) {
printf(" fib(%d) = %ld\n", fibcache(i));
}
return 0;
}
long fibcache(int n) {
if (n <= 0)
return 0;
if (n == 1)
return 1;
if (n < DCACHE_SIZE) {
if (fibcache_values[n] != 0)
return fibcache_values[n];
else
return fibcache_values[n] = fibcache(n - 1) + fibcache(n - 2);
} else {
return fibcache(n - 1) + fibcache(n - 2);
}
}
Related
trying to solve an assignment question...
info I have is:
foo(0)=0
foo(1)=1
foo(2)=2
the below code works upto approximately 30 numbers...but it needs to work fluently until 100, so I need to optimize it. I tried to create an equation which links every successive number but it did not work. Any ideas how to optimize it?
#include <stdio.h>
#include<stdlib.h>
long foo(int n) {
long a;
if (n==0)
{
return 0;
}
else if(n==1)
{
return 1;
}
else if(n==2)
{
return 2;
}
else
{
return foo(n-1)-2*foo(n-2)+foo(n-3)-2;
}
}
int main(void) {
long b=foo(7);
printf("%ld",b);
}
For such a simple problem, you can make the function iterative.
#include <stdint.h>
uint64_t foo (int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else if (n == 2)
return 2;
else
{
uint64_t a = 0, b = 1, c = 2;
uint64_t ret;
for (int i = 2; i<n; i++)
{
ret = a + 2*b + c - 2;
a = b;
b = c;
c = ret;
}
return (ret);
}
}
If you have to use recursion, you can significantly improve runtime with memoisation. In this case, you need an extra array to store the results of already calculated values.
uint64_t memo[101]; // size this array to the maximum value of n needed to be calculated.
uint64_t foo(int n) {
uint64_t a;
if (n==0)
{
return 0;
}
else if(n==1)
{
return 1;
}
else if(n==2)
{
return 2;
}
else
{
if (memo[n] == 0)
{
a = foo(n-1)-2*foo(n-2)+foo(n-3)-2;
memo[n] = a;
}
else
{
a = memo[n];
}
return a;
}
}
My code is supposed to count the number of zeroes using recursion.
However my program keeps crashing.
Expected output:
Input: 10500
Result: 3
Code:
void rCountZeros2(int num, int *result) {
if (num > 0) {
if ((num % 10) == 0) {
rCountZeros2((num / 10) + 1, *result);
}
rCountZeros2(num / 10, *result);
} else if (num == 0) {
*result = 1;
}
*result = num;
}
How do I make it work?
Here's the solution with and without using pointers
Hope this helps
#include <stdio.h> // For C++ #include<iostream>
// Without using pointer
int count_zeros_recursive2(int num) {
if (num % 10 == 0) {
if (num > 19 || num < -19) {
return 1 + count_zeros_recursive2(num / 10);
}
return 1;
}
if (num > 19 || num < -19) {
return count_zeros_recursive2(num / 10);
}
return 0;
}
// Using pointer
void count_zeros_recursive(int num, int *result) {
if (num % 10 == 0)
*result = *result + 1;
if (num > 19 || num < -19)
count_zeros_recursive(num / 10, result);
}
int count_zeros(int num) {
int result = 0;
count_zeros_recursive(num, &result);
//result = count_zeros_recursive2(num);
return result;
}
int main() {
int n;
while (1) {
scanf("%d", &n); // For C++ std::cin >> n;
printf("%d\n", count_zeros(n));// For C++ std::cout << n << "\n";
}
return 0;
}
eg Input: 1010
Output: 2
Input: 0
Output: 1
Input: 10204012410
Output: 4
Input: -101
Output: 1
I prefer returning the result instead of passing the pointer to the result.
Stop condition is when the number is a single digit, then if 0 you have 1 zero, otherwise none.
If the number is not a single digit, calculate the number of zeros in the number without the lowest digit (num/10) and add 1 to the returned value if the lowest digit was 0.
#include <stdio.h>
int count_zeros_recursive(int num)
{
int res = 0;
int num_without_lowest_digit = num/10;
if(num_without_lowest_digit == 0)
{
res = (num == 0);
}
else
{
res = count_zeros_recursive(num_without_lowest_digit);
if (num % 10 == 0)
{
res++;
}
}
return res;
}
int main(void) {
int nums[] = { 202, 7, 100, 10500, 10234, 10000};
int i;
for (i=0; i < sizeof(nums)/sizeof(nums[0]); ++i)
{
printf("Number %d has %d zeros\n", nums[i], count_zeros_recursive(nums[i]));
}
return 0;
}
Tested here
Number 202 has 1 zeros
Number 7 has 0 zeros
Number 100 has 2 zeros
Number 10500 has 3 zeros
Number 10234 has 1 zeros
Number 10000 has 4 zeros
Let's say you really want to use a pointer for some reason. Here's a full solution:
#include <stdio.h>
void rCountZeros2(int num, int *result)
{
if(num>0)
{
if( (num % 10) == 0)
{
*result = *result + 1;
}
rCountZeros2(num/10, result);
}
}
int main() {
int i = 0;
int n;
n = scanf("%d", &n);
int *result = &i;
rCountZeros2(n, result);
printf("%d\n", *result);
}
So what will happen is that you're effectively just updating the value at the location which result is pointing to, which means that you're really just storing the count in the variable i.
There is no need to pass a pointer if you can use a functional approach. Just return the value.
long recursiveZeroesCount(long num) {
if(num == 0) return 1;
if(num < 10) return 0;
if(num % 10 == 0) return 1 + recursiveZeroesCount(num / 10);
else return recursiveZeroesCount(num / 10);
}
Your program has undefined behavior because you pass the value of the *result instead of the pointer to the result variable to recursive calls. Furthermore, your algorithm is flawed as you cannot use this API recursively because the recursive calls update the result as well as the current call, a very impractical situation.
Here is a corrected version without recursion:
void rCountZeros2(int num, int *result) {
int count = 0;
for (;;) {
if (num % 10 == 0)
count++;
num /= 10;
if (num == 0)
break;
}
*result = count;
}
And here is a recursive implementation with a simpler API:
int rCountZeros2(int num) {
if (num % 10 == 0) {
if (num == 0)
return 1;
else
return 1 + rCountZeros2(num / 10);
} else {
if (num < 10)
return 0;
else
return rCountZeros2(num / 10);
}
}
The above function can be simplified as a single statement:
int rCountZeros2(int num) {
return !(num % 10) + ((num < 10) ? 0 : rCountZeros2(num / 10));
}
I have this code that the input is random for example :
33 32 65 55 44 pe *&44^ %123^
now I need to find which two digit number was repeaed most (and the number needs to contain digits from 1 to 9, which mean 10,30.. are not valid numbers), now what seperate between two digit number to another is every input exept for another number,
in this case I want the output to be 44 then I will print:
The winner couple is: 4 blue, 4 red.
now I thought the best way to do something like this is using 2D array, that when a input is valid I will apdate the array in the sutble place, and after that I will find the maximum place in the array.
here is my code so far :
#include <stdio.h>
#include <stdlib.h>
#define N 9
int is_digit(char c);
void update_array(int num[N][N]);
int find_max(int b[N][N]);
int main()
{
int i,j;
int num[N][N];
int maximum=0,a=0,b=0;
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
{
num[i][j]=0;
}
}
update_array(num);
maximum=find_max(num);
a=maximum/10;
b=maximum%10;
printf("The winner couple is: %d blue, 4%d red.",a,b);
return 0;
}
int is_digit(char c)
{
if(c<'0'&&c>'9')
return 1;
else
return 0;
}
void update_array(int num[N][N])
{
char c;
int digit = 0;
int digits = 0;
int redIndex = 0;
int blueIndex = 0;
while (scanf("%c", &c) != EOF)
{
if (is_digit(c))
{
digits++;
digit = c -'0';
if (digits == 1)
redIndex = digit;
else if (digits == 2)
blueIndex = digit;
}
else
{
if (digits == 2)
{
(num[redIndex][blueIndex]++);
}
digits = 0;
}
}
int find_max(int b[N][N])
{
int max = b[0][0];
int x,y;
for (x = 0; x < N; x++)
{
for (y = 0; y < N; y++)
{
if (max < b[x][y])
{
max = b[x][y];
}
}
}
}
return max;
}
the code gives me incorect output , i chicked all of the functions and they are good ,exept for update_array function i think there is something icorrect, basicly this function chicks where there is two digit number and update the suatble place in array, so i can then use fin_max function and find the maximum..
plz anyhelp of why it gives me incorect values, i know i should use debugg but i never knew about this untill now and i don't have the time to learn this now and use it cause i need to submit this in a couple of hours !
In your code you do if (isdigit(c)), but isdigit is a different (standard library) function! You have to #include <ctype.h> to use it.
Using continue; outside loop is illegal.
You didn't declare nor define w.
A semicolon is missing after what seems calling of function w.
Try this because is_digit is not used:
void is_digit(char c)
{
(void)c; /* avoid warning for unused variable */
}
Note that this is invaiid because the return type is void:
void is_digit(char c)
{
return (c>'0'&&c<='9');
}
Don't forget to add #include <ctype.h> to use isdigit().
Also, replace
if (isdigit(c))
with
if (isdigit((unsigned char)c) && c != '0')
to avoid undefined behavior for passing out-of-range value and reject digit 0.
You've declared the function with the name is_digit() and later you are using it with the name isdigit().
So, after changing the above mentioned error, your code would look like
#include <stdio.h>
#include <stdlib.h>
#define N 9
int is_digit(char c);
void update_array(int num[N][N]);
int find_max(int b[N][N]);
int main()
{
int i,j;
int num[N][N];
int maximum=0,a=0,b=0;
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
{
num[i][j]=0;
}
}
update_array(num);
maximum=find_max(num);
a=maximum/10;
b=maximum%10;
printf("The winner couple is: %d blue, 4%d red.",a,b);
return 0;
}
int is_digit(char c)
{
if(c<'0'&&c>'9')
return 1;
else if(c>'0'&&c<='9')
return 0;
}
void update_array(int num[N][N])
{
char c;
int digit = 0;
int digits = 0;
int redIndex = 0;
int blueIndex = 0;
while (scanf("%c", &c) != EOF)
{ // <= while started
if (is_digit(c))
{ // <= if started
digits++;
digit = c -'0';
if (digits == 1)
redIndex = digit;
else if (digits == 2)
blueIndex = digit;
} // <= If ended
else
{ // <= else started
if (digits == 2)
{
(num[redIndex][blueIndex]++);
}
digits = 0;
} // <= else ended
} // <= while ended
//where is the function ending?
} //hence another curly braces needed.
int find_max(int b[N][N])
{
int max = b[0][0];
int x,y;
for (x = 0; x < N; x++)
{
for (y = 0; y < N; y++)
{
if (max < b[x][y])
{
max = b[x][y];
}
}
}
return max;
}
I have a small problem I want to build a function that returns with recursive function the nn expression with one parameter in the calling function. Can someone help me? My thought so far :
int powerThroughRecursion(int n) {
if (n == 0) {
return 1;
}
if (n <= 1) {
return n;
}
return n * powerThroughRecursion(n - 1);
}
Yes, you are actually computing n! there. One way to do it is the following:
#include <iostream>
#include <string>
int powerThroughRecusion(int n, int step) {
if (step < 1)
return 1;
return n * powerThroughRecusion(n, step - 1);
}
int main()
{
std::cout << powerThroughRecusion(4, 4);
}
You multiply by n, but a step will tell you how much multiplications to be done.
[edit] using a single parameter function
#include <iostream>
#include <string>
int powerThroughRecusionInternal(int n, int step) {
if (step < 1)
return 1;
return n * powerThroughRecusionInternal(n, step - 1);
}
int powerThroughRecusion(int n)
{
return powerThroughRecusionInternal(n, n);
}
int main()
{
std::cout << powerThroughRecusion(2) << "\n";
std::cout << powerThroughRecusion(4);
}
If you want a one parameter function. just hide and wrap the two parameter implementation version with another function call.
static int powerThroughRecusionImpl(int n, int power) {
if (power == 0) {
return 1;
}
if (power == 1) {
return n;
}
return n * powerThroughRecusionImpl(n ,power - 1);
}
int powerThroughRecusion(int n) {
return powerThroughRecusionImpl(n ,n);
}
Or if you want to be non thread-safe.
int powerThroughRecusion(int n) {
static int base = 0;
if (!base) {
base = n;
n = powerThroughRecusion(n);
base = 0;
return n;
} else {
if (n == 0) {
return 1;
} else if (n == 1) {
return base;
}
return base * powerThroughRecusion(n - 1);
}
}
I got an excersice to make a string calculator which only has an add function. When digits are not seperated, the digits have te make one whole number. When the input is 11 the program may not do 1 + 1 but has to make it eleven.
When I execute the following program it is printing "Sum = 111" on my screen, does anyone know why it is not printing 11 and maybe has a solution?
int main(void)
{
int sum = Add("11");
if(sum == -1)
{
printf("Can not return a sum");
}
else
{
printf("Sum = %d\n", sum);
}
}
extern int Add(char* numbers)
{
size_t string_length = strlen(numbers);
int Sum = 0;
int index = 0;
char number_string[255];
int number = 0;
if(string_length == 0)
{
Sum = 0;
return Sum;
}
else if(string_length == 1)
{
if(isdigit(numbers[0]))
{
Sum = numbers[0] - '0';
}
else
{
return -1;
}
return Sum;
}
else if(string_length >= 2)
{
for(index; index <= string_length; index++)
{
if(isdigit(numbers[index]))
{
strcat(number_string, &numbers[index]);
}
else if(!isdigit(numbers[index]))
{
Sum += atoi(number_string);
memset(number_string, 0, 255);
}
else
{
return -1;
}
}
return Sum;
}
else
{
return -1;
}
}
you function uses strcat, you can debug and see how it works:
1st iteration - append string "11" (&numbers[0] points to begin of the string) to number_string
2nd iteration - append string "1" (&numbers[1] points to 2nd symbol) to number_string
this is how you get "111"
what you need to do is to convert your string to number without concatenation, like this:
int Add(char* numbers) {
int n = 0;
for (; *numbers; numbers++)
if (isdigit(*numbers))
n = n*10 + (*numbers - '0');
return n;
}
Your strcat cats 11 and then cats 1 to number string, so you the 111. Here is a simple way to do this without any built in functions other than printf.
#include <stdio.h>
int main(int argc, char *argv[])
{
int sum = -1;
printf("%d\n", argc);
if (argc == 2) {
sum = Add(argv[1]);
}
if(sum == -1)
{
printf("Can not return a sum\n");
}
else
{
printf("Sum = %d\n", sum);
}
}
int Add(char* numbers)
{
char *ptr = numbers;
char *end = numbers;
int sum = 0;
while (*end >= '0' && *end <= '9') {
end++;
}
for( ; ptr < end; ptr++) {
sum *= 10;
/* *ptr is always positive */
sum += *ptr - '0';
}
return sum;
}