The statement of my problem is this:
Write a recursive function that takes a natural number as argument and returns the value of the number read backwards (with the decimal digits in opposite order):
E.g : f(3120) = 213
I have solved the problem but I used static to store my reversed number as in the code below:
unsigned long f(unsigned long n){
static long rev;
if(n==0)
return 0;
else
{
rev=rev*10+n%10;
f(n/10);
}
return rev;
}
but I would like to know if there is a way to solve this problem without using the static data type and still keeping only one parameter in the function.
Of course. Just remove the word static from your code and do calulations in loop:
unsigned long f(unsigned long n){
long rev = 0;
while(n != 0) {
rev = rev*10 + n%10;
n /= 10;
}
return rev;
}
You could put current result as an argument of your function:
int f(int x, int r = 0)
{
if (x == 0) return r;
return f(x / 10, r * 10 + x % 10);
}
Related
I tried to build a recursion function using pointers that puts the digits with an even index in one pointer and the digits with the odd index to a different one.
For example:
The input 123: 3 has the index of 0 so it will go to *even.
2 has the index of 1 so it will go to *odd.
1 has the index of 2 so it will go to *even.
and in the end *even will have the value of 1+3 = 4 and *odd will have the value of 2.
But I had problems with this function so I tried to do a simplified version of it and It didn't work.
So the simplified version puts the sum of all the digits in *sum:
void main()
{
int num = 25;
int x = 0;
sumDigits(num, &x);
printf("%d", x);
}
void sumDigits(int num, int* sum)
{
if (num >= 0 && num <= 9)
{
*sum = num;
}
else
{
*sum = *sum + num % 10;
sumDigits(num/10, sum);
}
}
But it still won't work properly.
If someone could tell me what's wrong with this function then I could understand how to it and the original one as well.
A simple solution is to handle both an even and an odd digit in each function call.
Like:
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
// Handle even digit
*even += num % 10;
num /= 10;
// Handle odd digit
*odd += num % 10;
num /= 10;
// If there are still digits to be handled
if (num)
{
// Do the recursive call
sumDigits(num, even, odd);
}
}
int main(void)
{
unsigned int num = 123;
unsigned int even = 0, odd = 0;
sumDigits(num, &even, &odd);
printf("even=%d odd=%d", even, odd);
}
That said... this problem is not suitable for recursion a simple loop will be much more efficient.
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
while (num)
{
*even += num % 10;
num /= 10;
*odd += num % 10;
num /= 10;
}
}
For starters the function sumDigits must be declared before main and according to the C Standard the function main without parameters shall be declared like
int main( void )
That is you need to write
#include <stdio.h>
void sumDigits(int num, int* sum);
int main( void )
{
//...
}
There is neither sense to declare the first parameter of the function as having the signed integer type int because it seems the function does not deal with negative numbers.
The first parameter should have the type unsigned long long. In this case you can call the function for an object of any fundamental unsigned integer type.
The function has a logical error. Its last recursive call overwrites the value stored in sum that was calculated in preceding recursive calls of the function due to this if statement
if (num >= 0 && num <= 9)
{
*sum = num;
}
Also pay attention to that the user can pass by reference the second argument that was not initialized. In this case the function will have undefined behavior.
As for your mentioned function that should calculate suns of digits in even and odd positions then it can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void digits_sums( unsigned long long int x, unsigned int *even, unsigned int *odd )
{
const unsigned long long int Base = 10;
x == 0
? ( *even = x, *odd = x )
: ( digits_sums( x / Base / Base, even, odd ), *even += x % Base, *odd += x / Base %Base );
}
int main(void)
{
unsigned int x = 123456789;
unsigned int even;
unsigned int odd;
digits_sums( x, &even, &odd );
printf( "The sum of digits in even positions is %u\n"
"The sum of digits in odd positions is %u\n",
even, odd );
return 0;
}
The program output is
The sum of digits in even positions is 25
The sum of digits in odd positions is 20
I encountered a hard question I don't know the answer to: "Rearrange the digits from an integer in blocks of two with a recursive function" here's an example:
Input: 123456
unsigned long pairinvPrint(unsigned long number) {
printf("%d", number % 100);
if ((number / 100) <= 99) {
printf("%d", number / 100);
}
else {
pairinv(number / 100);
}
}
Output: 563412
More I/O Examples: 42 -> 42; 1234 -> 3412
However, the set circumstances to do this are hard (no loops, arrays, pointers, global- or static variables, no libraries) and it should not print the solution directly, rather return it upon a call like this:
printf("Rearrange int (%lu) = %lu", input, pairinvert(input));
Luckily there's one circumstance to make it easier, the number of the input digits is always even.
Now I experimented for a while, but cant come up with a working solution, except the invalid one using printf.
Does anyone have some inspiration for me or idea how to tackle this?
I'll bite :-)
unsigned long p(unsigned long p1, unsigned long p2) {
// no loops, no arrays, no pointers, no global, no static, no variables, no libraries
if (p1 < 100) return p2*100 + p1;
return p(p1/100, p2*100 + p1%100);
}
unsigned long pairinvert(unsigned long n) {
// no loops, no arrays, no pointers, no global, no static, no variables, no libraries
if (n < 100) return n;
return p(n/100, n%100);
}
// need <stdio.h> for printf()
#include <stdio.h>
int main(void) {
unsigned long input;
input = 123456;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
input = 42;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
input = 1234;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
}
Following program should work.
#include <stdio.h>
void rearrange(int n, int *output) {
int lsd = 0, slsd = 0;
if(n == 0)
return;
if(n > 0) {
lsd = n%10;
}
if (n > 9) {
slsd = (n%100)/10;
}
*output = 100*(*output) + 10*slsd + lsd;
n = n/100;
rearrange(n, output);
}
int main() {
int n;
int output = 0;
scanf("%d", &n);
rearrange(n, &output);
printf("%d\n", output);
return 0;
}
It is simple to understand, so I am not writing any comments.
Note that it is tail recursive so with O2 optimization it can recurse infinitely.
Try this :
unsigned long pairinv(unsigned long number, unsigned long result) {
unsigned long n = number % 100; // Gets the two digit number
if (n == 0) return result; // If it's zero returns the result
result = result * 100 + n; // Else multiplies the result by 100, adds n
return pairinv(number / 100, result); // and continues by recursion
}
int main() {
unsigned long r= 0;
printf("%lu\n", pairinv(123456, r)); //==> 563412
return 0;
}
Doing the 7. Reverse Integer leetcode, (intput =321 expected output = 123)
I don't know how to return my numbers from the function. I'm printing them as of right now to see if I'm solving the problem, and my stdout is fine but my output is 3.
Your input:
123
stdout:
312
Output:
3
Expected:
321
int reverse(int x)
{
int a,b,c;
c = x % 10;
b = (x / 10) / 10;
a = (x / 10) % 10 ;
printf("%d%d%d",c,b,a);
return;
}
It might be easier to generalize reverse to handle numbers of any width, not just 3 digits.
Here's some code to do that (you might have to adjust the format for the printf):
#include <stdio.h>
int
reverse(int x)
{
int y = 0;
while (x != 0) {
y *= 10;
y += (x % 10);
x /= 10;
}
return y;
}
int
main(void)
{
const char *fmt = " %3.3d";
for (int x = 0; x <= 999; ++x) {
printf(fmt,x);
printf(fmt,reverse(x));
printf("\n");
}
return 0;
}
Generalizing a bit and handling potential negative values. You have the basic approach, but, in addition, you want to determine the sign of the input and then operate on a positive value and restore the sign at the end of your function. You can do something similar to:
#include <stdio.h>
#include <stdlib.h>
int reverseint (int n)
{
int reverse = 0,
sign = n < 0 ? -1 : 1;
if (n < 0)
n = -n;
while (n) {
reverse *= 10;
reverse = reverse + n % 10;
n /= 10;
}
return sign * reverse;
}
A short example main() to demonstrate that takes the number to reverse as the first argument to the program (or uses 54321 if no argument is given) could be:
int main (int argc, char **argv) {
int n = (argc > 1) ? (int)strtol(argv[1], NULL, 0) : 54321;
printf ("n : %d\nreverse : %d\n", n, reverseint(n));
}
(note: you should validate the input to the program and the reverseint function are valid integers is in the range of int -- that is left to you)
Example Use/Output
$ ./bin/reverseint
n : 54321
reverse : 12345
$ ./bin/reverseint 0
n : 0
reverse : 0
$ ./bin/reverseint -12345
n : -12345
reverse : -54321
Alternative Using div()
The div() function also provides a nice variant that will replace both your division and modulo operations. See man 3 div. The following is equivalent to the function above but using div() instead of / and %:
int reverseint (int n)
{
/* initialize div_t with positive .quot */
div_t d = { .quot = n < 0 ? -n : n };
int reverse = 0,
sign = n < 0 ? -1 : 1;
do {
d = div (d.quot, 10); /* call div with base 10, to update quotient */
reverse *= 10; /* multiply reverse by 10 */
reverse += d.rem; /* add remainder of division */
} while (d.quot);
return sign * reverse;
}
Look things over and let me know if you have further questions.
As already said you mixed up a and b.
You can't return multiple values.
What you can do is create one number, pack the numbers in an array, pass the pointers to function, place in a struct. You could write something like this:
#include <stdio.h>
int reverse(int x)
{
int a,b,c;
int num;
c = x % 10;
b = (x / 10) % 10;
a = (x / 10) / 10 ;
num = c*100 + b*10 + a;
return num;
}
int main()
{
int x;
scanf("%d", &x);
int num = reverse(x);
printf("%d", num);
}
If you want to return all the values separately you can write something like this for example:
#include <stdio.h>
void reverse(int x , int *a, int *b, int *c)
{
*c = x % 10;
*b = (x / 10) % 10;
*a = (x / 10) / 10 ;
}
int main()
{
int x,a,b,c;
scanf("%d", &x);
reverse(x,&a,&b,&c);
printf("%d%d%d",c,b,a);
}
since you don't want to "return" a single number without the addition operation and display the reversed digits as a whole number there is a way of solving this via the usage of pointers. The code goes like this;
#include <stdio.h>
int* reverse(int);
int main() {
int inputnum;
int *p;
printf("Enter input number: ");
scanf("%d", &inputnum);
p=reverse(inputnum);
printf("\n Output number: ");
for(int i=0;i<3;i++){
printf("%d", *p );
p++;
}
return 0;
}
int* reverse(int x)
{
static int arr [3];
arr[0] = x % 10;
arr[1] = (x / 10) / 10;
arr[2] = (x / 10) % 10 ;
return arr;
}
As you can see, you don't need to use additional integer variables such as a,b,c since we will be storing the data of each operation you have done in a array and treat it as your new number as a whole in the output part. We do this since this is what you specifically asked in your question but there are so much more simpler ways on digit reversing etc. After returning the array that represents the new output number, we can ask our pointer to start from the first index of the array (which is the last digit of the input number in this case) untill the end. By increasing the pointer by 1 we display other digits of our input number as reversed. I hope this will be helpful
I working through a book on C on my own. This isn't homework to be turned in. I am writing a C program to determine the largest Fibonacci number my machine can produce. And instructed to use a nonrecursive method.
My Code:
#include<stdio.h>
double fibo(int n);
int main(void)
{
int n = 0; // The number input by the user
double value; // Value of the series for the number input
while (n >= 0)
{
// Call fibo function
value = fibo(n);
// Output the value
printf("For %d the value of the fibonacci series = %.0f\n", n,
value);
n++;
}
return 0;
}
double fibo(int n)
{
int i; // For loop control variable
double one = 0; // First term
double two = 1; // Second term
double sum = 0; // placeholder
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
{
for (i = 2; i <= n; i++)
{
sum = one + two;
one = two;
two = sum;
}
}
return sum;
Code works fine but I want to to break when the output gives me the fist instance of :
For 17127 the value of the fibonacci series = inf
Is there way to us an if statement like:
if (value == inf)
break;
The simplest is to use INFINITY or isinf().
Just did a little search and found this nice trick:
...
double value, temp; // Value of the series for the number input
while (n >= 0)
{
// Call fibo function
temp = fibo(n);
if (temp - temp != 0)
break;
else
value=temp;
...
well it turns out that whats happening is when temp hits Inf the if condition temp - temp produces Nan which equals nothing and the rest is just executing break; to exit the process.
I want to to break when the output gives me the first instance of : inf
Simply test against INFINITY from <math.h>. The output will not be an exact Fibonacci number.
#include <math.h>
#include <stdio.h>
int main(void) {
double a;
double b = 0;
double c = 1;
do {
a = b;
b = c;
c = a + b;
} while (c < INFINITY);
printf("%e\n", b);
return 0;
}
Output
1.306989e+308
long double
Use the widest floating point type and look for an inexact addition.
#include <fenv.h>
#include <stdio.h>
int main(void) {
long double a;
long double b = 0;
long double c = 1;
do {
a = b;
b = c;
c = a + b;
} while (fetestexcept(FE_INEXACT) == 0);
printf("%.0Lf\n", b);
return 0;
}
Output
12200160415121876738
Integers
Use the widest type available. This is akin to #Syed.Waris unsigned long long approach. Although common that unsigned long long and uintmax_t have the same range, using uintmax_t insures the widest.
uintmax_t: The following type designates an unsigned integer type capable of representing any value of any unsigned integer type:
#include <stdint.h>
#include <stdio.h>
uintmax_t a;
uintmax_t b = 0;
uintmax_t c = 1;
do {
a = b;
b = c;
c = a + b;
} while(c >= b);
printf("%ju\n", b);
Output
12200160415121876738
String
An alternative to double or some int type, is to create a simple string add function str_add(), then quite easy to form large Fibonacci numbers.
int main(void) {
char fib[3][4000];
strcpy(fib[0], "0");
strcpy(fib[1], "1");
int i;
for (i = 2; i <= 17127 && strlen(fib[1]) < sizeof fib[1] - 1; i++) {
printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
strcpy(fib[0], fib[1]);
strcpy(fib[1], fib[2]);
}
printf("%zu\n", strlen(fib[2]));
return 0;
}
Output
Fib(1476) 13069...(299 digits)....71632. // Exact max `double`
Fib(17127) 95902...(3569 digits)...90818.
largest Fibonacci number my machine can produce
This question is not concerned with any data type but it is concerned with machine.
The basic rule of fibonacci is this:
n = (n-1) + (n-2)
You can take a big sized unsigned long long variable and you can keep on adding. But what if that datatype is overflowed? You are not concerned with data type. Your machine may produce a number even bigger than the long long. What would that number be ? Entire bits on RAM? Hard Disk ?
Since you are required to use an iterative method and not recursive method, your teacher/book/instructor might be testing you on loops (and not any standard API). Below is sample code using unsigned long long:
#include <stdio.h>
int main ()
{
unsigned long long a = 0;
unsigned long long b = 1;
unsigned long long c = a + b;
while(c >= b)
{
a = c;
c = b + c;
b = a;
}
printf("\n%llu\n", b);
return 0;
}
Output:
12200160415121876738
Everyone in the solutions are giving functions with if else statements and return statement which i don't want . I have clearly mentioned that there should be no if else and return statement . that's why in my program i also didn't use it
I want to know if we can write the factorial of a number using recursion without using any if-else statements and a return statement. If yes, then how?
I tried something like this:
int n;
int fact=1;
factorial(){
while(n){
fact= fact * n;
n--; factorial();
}
}
main(){
n = 5;
factorial();
printf("%d",fact);
}
The above program is correctly giving a factorial of the number but the recursive call is just a dummy here. The recursive call is not actually doing anything.
So is it possible to write a factorial of a number with recursion without return statement & ifelse where recursive calls are actually contributing to find the factorial
int result;
void factorial(int n)
{
(result = 1, n <= 1) || (factorial(n - 1), result *= n);
}
int main()
{
factorial(5);
printf("%d\n", result);
}
Or, better
void factorial(int *n)
{
int f;
(f = 1, *n <= 1) || (f = (*n)--, factorial(n), f *= *n);
*n = f;
}
int main()
{
int n = 5;
factorial(&n);
printf("%d\n", n);
}
Or, if ?: is allowed the last one can be rewritten without that || trickery
void factorial(int *n)
{
int s;
*n = *n <= 1 ? 1 : (s = (*n)--, factorial(n), *n * s);
}
I think you are using C in a wrong way, because to use the global variable n is wrong practice. It would have to be a parameter of the function factorial.
Once this issue is fixed, we can handle the problem you are asking for.
I see unnecessary to restrict ourselves to "not use" if-else sentences.
Anyway, it's easy to do it in C, since we have the ternary operator.
For example, the following:
char c = (3<4)? 'y': 'n';
is equivalent to:
char c;
if (3<4)
c = 'y';
else
c = 'n';
In the case of recursive factorial, we would have:
int factorial(int n) {
return (n <= 1)? 1: factorial(n-1);
}
Using a recursive helper function:
int helperfact(int *m, int *n){
*n>0 && ( *m *= (*n)--, helperfact(m, n));
}
void fact(int n){
int m = 1;
helperfact(&m,&n);
printf("%d\n",m);
}
int main(void){
fact(10);
fact(0);
return 0;
}
Output:
3628800
1
Your could try this:
int factorial (int t) /*t = factorial*/
{
int r; /*result*/
if (t == 1) /*if t = 1 the recursion will end*/
{
return 1;
}
r = t * factorial(t - 1) ; /*calling the function again with times - 1*/
return r; /*will make recursion until t = 1 */
}
Hope it works.