How to Print All N-digit Numbers Recursively in C? - c

I'm trying to print all N-digit numbers with a given phrase recursively (excluding 0).
For example, given input:
void rec_fun ( "Hello" , 2 )
My output would be:
Hello 11
Hello 12
Hello 13
Hello 14
Hello 15
...
Hello 21
Hello 22
Hello 23
Hello 24
...
Hello 96
Hello 97
Hello 98
Hello 99
Some hints that I had:
Use dynamic memory
loop would only be used once and in the Stop condition.
Given function is:
void rec_fun ( int char* , int num );
My try, which didn't work, but I'm posting to get some directions:
void rec_fun ( char* c , int num ){
if (num == 0){
printf("%s",c);
}
int flag = 1;
if (num>0){
while(flag){
for(int i=1 ; i<num+1 ; i++){
printf("%d",i);
rec_fun (c, num-1);
printf("\n");
flag = 0;
}
}
}
}
Would love to get some help on this !

Some hints That I had :
Use dynamic memory
loop would only be used once and in the Stop condition.
I don't see the value in these hints. This is a single-loop algorithm, so the loop can be replaced completely with recursion (but shouldn't be, other than placating contrived assignment requirements, because recursion is less efficient, harder to write in this case, and can blow the stack easily on linear algorithms in language implementations that don't support tail recursion--but we'll play along).
Dynamic memory isn't needed to count here and I'm not sure how that'd factor in.
A good hint would be something along the lines of: what's the base case, and how does the parameter num allow you to approach the base case on each call? If the initial call is rec_fun("Hello", 2), how do you know you should print 11 and stop at 99?
The bad way to solve the problem is to use global data, but unnecessarily shared state makes the function brittle, non-rentrant and hard to debug.
Better to use a separate helper function that does the actual recursion, accepting the current value of n and therefore lets you approach a base case.
After that, there's the detail of figuring out how to convert the number of digits to the actual digits. Exponents are the key: 10 ** (n - 1) for the start (inclusive) and 10 ** n for the stop (exclusiive), where ** is exponentiation.
#include <math.h>
#include <stdio.h>
void print_n_to_end_with_prefix_recursive(
const char *prefix, const int n, const int end
) {
if (n < end) {
printf("%s %d\n", prefix, n);
print_n_to_end_with_prefix_recursive(prefix, n + 1, end);
}
}
void print_n_digit_numbers_with_prefix(const char *prefix, const int n) {
int start = pow(10, n - 1);
int stop = pow(10, n);
print_n_to_end_with_prefix_recursive(prefix, start, stop);
}
int main(void) {
print_n_digit_numbers_with_prefix("Hello", 2);
return 0;
}
If you want to exclude 10, 100, etc, then add 1 to start before kicking off the recursion for values of n > 1. You can also handle the 0-digit case specially if you want. The program will crash on large numbers of n, so some validation is recommended.

This uses recursion to add 1 digit each level:
void rec_fun(char * str, int num, int num_digits)
{
if (num_digits == 0) {
printf("%s %d\n", str, num);
} else {
// Need more digits, so call recursively.
for (int i = 1; i < 10; i++)
rec_fun(str, num * 10 + i, num_digits-1);
}
}
int main(int argc, char const *argv[])
{
rec_fun("Hello", 0, 2);
}
Output
Hello 11
Hello 12
Hello 13
Hello 14
Hello 15
...
Hello 99

You can try following:
#include <stdio.h>
void helper(char * c, int num, int digits)
{
if (digits) {
int i = 1;
while(i <= 9) {
helper(c, num * 10 + i, digits-1);
i++;
}
} else {
printf("%s %d\n", c, num);
}
}
void rec_fun(char * c, int num) {
helper(c, 0, num);
}
int main()
{
rec_fun("Hello", 2);
return 0;
}
Time complexity: O(10^N) [N is num (for example, 2 in question)].
Space complexity: O(1) [No extra space needed, call stack for recursion is ignored]
Note: Recursion will not work after N becomes larger.

Related

I need to calculate the reverse of a number using pointers to functions

So I need to calculate the reverse of a number using pointers in a function. I get junk memory when I run it.Here is what I tried.(When I remove the p ,it works, I don't get any junk memory but than I can calculate only the remainder , I don't get why?)
I m sorry for the earlier post. I read the rules of Stack Overflow.
Here is the code:
int Invers(int x , int *Calculinvers ){
int rem = 0;
int p = 1
while(x!=0){
rem = x % 10 ;
*Calculinvers = p*10 + rem;
x = x / 10;
}
return *Calculinvers;
}
int main(){
int a;
printf("Introduceti numarul caruia vreti sa-i calculati inversul : \n");
scanf("%d" , &a);
int Calcul;
Invers(a , &Calcul);
printf("Inversul numarului este : %d\n" , Calcul);
return 0;
}
Two problems and fixes:
(1)*Calculinvers needs to be initialized to 0, or system will give you unexpected value.
(2)Replace *Calculinvers = p*10 + rem; to *Calculinvers = *Calculinvers*10 + rem; because you did not add the previous value.
I threw together this, it seems to work:
#include <stdio.h>
int reverse(int x)
{
out = 0;
while (x != 0)
{
const int ones = x % 10;
out *= 10;
out += ones;
x /= 10;
}
return out;
}
int main(void) {
const int num[] = { 0, 1, 10, 47, 109, 4711, 1234, 98765432 };
printf("I got:\n");
for (int i = 0; i < sizeof num / sizeof *num; ++i)
{
printf(" %d -> %d\n", num[i], reverse(num[i]));
}
return 0;
}
It prints:
I got:
0 -> 0
1 -> 1
10 -> 1
47 -> 74
109 -> 901
4711 -> 1174
Obviously when we're working with actual integers, trailing zeroes turn into leading zeroes which don't really exist unless we store the original number's length and pad when printing. That's why 10 turns to 1, for instance.
This is better suited as a pure string-space operation, since then each digit exists as part of the string rather than as part of the representation of a number (which has other conventions).
Update:
If you really want to use pointers, you can of course wrap the above in a more pointery shroud:
void reverse_at(int *x)
{
const int rev = reverse(*x);
*x = rev;
}
but as stated in comments (and hopefully illustrated by my code) a more functional approach where the return value calues the result of a function is generally more easily understood, safer, and just better.

Base case of recursion function for Fibonacci sequence

I'm trying to write the function void fib(int arr[], int n), which would fill the array with Fibonacci numbers until index n.
I've tried to find base cases, and chose these:
void fib(int arr[], int num){
int arrLength = num + 1;
if(num<0){
return;
}else if(num == 0){
arr[num] = 1;
}else if(num == 1){
arr[num-1] = 1;
arr[num] = 1;
}
}
But, as you can see, I did not find recursive method itself.
Here's sample output, for example, for call fib(arr, 5):
0 1 2 3 4 5
1 1 2 3 5 8
My main function for testing case:
int main(){
int n = 10, i;
int arr[n+1];
fib(arr, n);
for(i=0;i<=10;i++){
printf("%i ", arr[i]);
}
return 0;
}
Is there any other way to make base cases more "elegant"? Also, I would truly appreciate hints using which I could fill the array with numbers starting from 2 with recursive option.
You question is asking for recursion but the program you write is just using function, because of this reason I am writing very basic code for your better understanding, you can improve this after understanding the flow and functionality or ask new question with some work.
Below one is a working code tested on TurboC, I am sharing complete test code.
#include <stdio.h>
#include<conio.h>
#define MAX 100
void fib(int *arr, int num, int a, int b, int term){
if(term == 0 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term ==1 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term <= num){
arr[term] = a+b;
term++;
fib(arr,num,b,a+b,term);
}
}
void main()
{
int firstTerm = 1;//First term of fibbo series
int secondTerm = 1;//Second term of fibbo series
int tracker = 0; // Tracker to track how much term we printed
int i;//To run loop here to check array after recursive function
int ar[MAX],n=5;// n is number of term we want to print
clrscr();
fib(ar,n,firstTerm,secondTerm,tracker);//recursive function call
// below is printing array to check
for(i=0;i<=n;i++){
printf("%d\t",ar[i]);
}
getch();
}
One thing I have to suggest is, if n is 5 then you just get 1 1 2 3 5, In code I did according to your requirement, so here it will print 1 1 2 3 5 8
I'd state that the "elegant" solution should be a simple loop, without any recursion, but let's see how it could be done in the less efficient and more error prone way.
// I'll assume that the function signature can't be changed
void fib(int arr[], int num)
{
// In the general case, use the well known recurrence relation.
if ( num > 1 )
{
// Use recursion here to calculate the previous elements of the array.
fib(arr, /* ... */);
// ^^^^^^^^^ Can you figure out what index should be passed here?
// Then, calculate the element at index num using the recurrence relation.
arr[num] = arr[num - 1] + arr[num - 2];
// ^^^^^^^ ^^^^^^^ Note the indices.
// Are those values alredy known?
}
// When num is 0 or 1, we can't use the general formula. Can you tell why?
else if ( num >= 0 )
{
fib(arr, /* ... */);
// ^^^^^^^^^ Same as before.
arr[num] = 1;
}
// If num is less than 0, it just do nothing.
}

Why is my pthread program missing prime numbers?

I am working on a program that utilizes pthreads in C. The function of the thread is to compute prime numbers based on a maximum number entered by the user at the CLI. Thus say for instance, the user enters ./ComputePrimes 20, the output should be 2, 3, 5, 7, 11, 13, 17, 19.
However, for some reason, my program only outputs 2 to 13 (thus my output is 2, 3, 5, 7, 11, 13).
I am using a formula based off of Wilson's Theorem for computing primes:
https://en.wikipedia.org/wiki/Formula_for_primes
I know from a Discrete Mathematics class I have taken in the past that there is no solid formula for computing primes. The purpose of this program however is to demonstrate pthreads which I believe I have done successfully. Here is my program:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *generatePrimeNumbers(void *primenum) {
int i, j, a, b;
int primeNumbers[] = {};
int limit = (int *)primenum;
for (i = 1; i <= limit; i++) {
j = 0;
int a = (factorial(i) % (i + 1));
int b = (i - 1) + 2;
if (((a / i) * b) != 0) {
primeNumbers[j] = ((a / i) * b);
printf("%d ", primeNumbers[j]);
j++;
}
}
printf("\n");
return NULL;
}
int factorial(int n) {
if (n == 1) {
return 1;
} else return n * factorial(n - 1);
}
int main(int argc, char *argv[]) {
int numLimit;
pthread_t primethread;
if (argc != 2) {
printf("You need to enter a valid number!\n");
exit(-1);
}
else {
int i = 0;
numLimit = atoi(argv[1]);
if (numLimit < 2) {
printf("Please enter a number greater than or equal to 2.\n");
exit(-1);
}
}
pthread_create(&primethread, NULL, generatePrimeNumbers, (void *)numLimit);
pthread_exit(NULL);
}
As you can see below, I successfully create a thread, however some of the prime numbers are missing. I believe that I might have messed up somewhere in my called threads function. Thanks!
In many environment, int can only store integers only upto 2147483647 (2**31 - 1) while 20! = 2432902008176640000. Therefore, factorial(20) cannot be calculated correctly.
Making the return type of factorial to long long will make the output for input 20 correct (supposing that long long can save upto 2**63 - 1), but for larger number, you should consider other method such as taking modulo inside factorial method before the number gets too big.
Also note that the line
int limit = (int *)primenum;
looks weird. The cast should be int, not int *.
Another point is that you are assigning numbers to 0-element array as Retired Ninja said.
In this code, primeNumbers isn't used other than the printing point, so the printing should be done directly like
printf("%d ", ((a / i) * b));

What is wrong with my hash function?

I'm trying to create a hash table. Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define N 19
#define c1 3
#define c2 5
#define m 3000
int efort;
int h_table[N];
int h(int k, int i)
{
return (k + i*c1 + i*i*c2) % N;
}
void init()
{
for (int i = 0; i < N; i++)
h_table[i] = -1;
}
void insert(int k)
{
int position, i;
i = 0;
do
{
position = h(k, i);
printf("\n Position %d \n", position);
if (h_table[position] == -1)
{
h_table[position] = k;
printf("Inserted :elem %d at %d \n", h_table[position], position);
break;
}
else
{
i += 1;
}
} while (i != N);
}
void print(int n)
{
printf("\nTable content: \n");
for (int i = 0; i < n; i++)
{
printf("%d ", h_table[i]);
}
}
void test()
{
int a[100];
int b[100];
init();
memset(b, -1, 100);
srand(time(NULL));
for (int i = 0; i < N; i++)
{
a[i] = rand() % (3000 + 1 - 2000) + 2000;
}
for (int i = 0; i < N ; i++)
{
insert(a[i]);
}
print(N);
}
int main()
{
test();
return 0;
}
Hash ("h") function and "insert" function are took from "Introduction to algorithms" book (Cormen).I don't know what is happening with the h function or insert function. Sometimes it fills completely my array, but sometimes it doesn't. That means it doesn't work good. What am I doing wrong?
In short, you are producing repeating values for position often enough to prevent h_table[] from being populated after only N attempts...
The pseudo-random number generator is not guaranteed to produce a set of unique numbers, nor is your h(...) function guaranteed to produce a mutually exclusive set of position values. It is likely that you are generating the same position enough times that you run out of loops before all 19 positions have been generated. The question how many times must h(...) be called on average before you are likely to get the value of an unused position? should be answered. This may help to direct you to the problem.
As an experiment, I increased the looping indexes from N to 100 in all but the h(...) function (so as not to overrun h_table[] ). And as expected the first 5 positions filled immediately. The next one filled after 3 more tries. The next one 10 tries later, and so on, until by the end of 100 tries, there were still some unwritten positions.
On the next run, all table positions were filled.
2 possible solutions:
1) Modify hash to improve probability of unique values.
2) Increase iterations to populate h_table
A good_hash_function() % N may repeat itself in N re-hashes. A good hash looks nearly random in its output even though it is deterministic. So in N tries it might not loop through all the array elements.
After failing to find a free array element after a number of tries, say N/3 tries, recommend a different approach. Just look for the next free element.

Reverse two numbers and obtain the reverse of the sum

I am coming to SO as a last resort. Been trying to debug this code for the past 2 hours. If the question is suited to some other SE site, please do tell me before downvoting.
Here it goes:
#include <stdio.h>
#include<math.h>
int reverse(int n) {
int count = 0, r, i;
int k = (int)log(n * 1.0);
for(i = k; i >= 0; i--)
{
r = (n % 10);
n = (n / 10);
count = count + (r * pow(10, k));
}
return count;
}
int main(void) {
int t;
scanf("%d", &t);
while(t--)
{
int m, n, res;
scanf("%d %d", &m, &n);
res = reverse(m) + reverse(n);
printf("%d", reverse(res));
}
return 0;
}
My objective is to get 2 numbers as input, reverse them, add the reversed numbers and then reverse the resultant as well.I have to do this for 't' test cases.
The problem: http://www.spoj.com/problems/ADDREV/
Any questions, if the code is unclear, please ask me in the comments.
Thank you.
EDIT:
The program gets compiled successfully.
I am getting a vague output everytime.
suppose the 2 numbers as input are 24 and 1, I get an output of 699998.
If I try 21 and 1, I get 399998.
Okay, if you had properly debugged your code you would have notices strange values of k. This is because you use log which
Computes the natural (base e) logarithm of arg.
(took from linked reference, emphasis mine).
So as you are trying to obtain the 'length' of the number you should use log10 or a convertion (look at wiki about change of base for logarithms) like this: log(x)/log(10) which equal to log10(x)
And now let's look here: pow(10, k) <-- you always compute 10^k but you need 10^i, so it should be pow(10, i) instead.
Edit 1: Thanks to #DavidBowling for pointing out a bug with negative numbers.
I don't know how exactly you have to deal with negative numbers but here's one of possible solutions:
before computing k:
bool isNegative = n < 0;
n = abs(n);
Now your n is positive due to abs() returning absolute value. Go on with the same way.
After for loop let's see if n was negative and change count accordingly:
if (isNegative)
{
count = -count;
}
return count;
Note: Using this solution we reverse the number itself and leave the sign as it is.
It looks like Yuri already found your problem, but might I suggest a shorter version of your program? It avoids using stuff like log which might be desirable.
#include <stdio.h>
int rev (int n) {
int r = 0;
do {
r *= 10;
r += n % 10;
} while (n /= 10);
return r;
}
int main (void) {
int i,a,b;
scanf("%d",&i);
while (i--) {
scanf("%d %d",&a,&b);
printf("%d\n",rev(rev(a) + rev(b)));
}
return 0;
}
Hopefully you can find something useful to borrow! It seems to work okay for negative numbers too.
Under the hood you get char string, reverse it to numeric, than reverse it to char. Since is more comfortable work with chars than let's char:
char * reverse (char *s,size_t len) //carefull it does it in place
{
if (!len) return s;
char swp, *end=s+len-1;
while(s<end)
{
swp =*s;
*s++=*end;
*end--=swp;
}
return s;
}
void get_num(char *curs)
{
char c;
while((c=getchar())!='\n')
*curs++=c;
*curs=0;
}
int main()
{
double a,b,res;
char sa[20],sb[20],sres[20],*curs;
get_num( sa);
get_num(sb);
reverse(sa,strlen(sa));
reverse(sb,strlen(sb));
sscanf(sa,"%f",&a);
sscanf(sb,"%f",&b);
res=a+b;
sprintf(sres,"%f",res);
reverse(sres);
printf(sres);
}

Resources