I'm having some problems with this C programming assignment that I have in school. I'm supposed to return the prime numbers from within a given range, and it has to be done using recursion.
The code I've got so far is this:
#include <stdio.h>
#include <stdlib.h>
int primeNumberList(int n, int m, int z);
int main() {
int n1 = 0,
n2 = 10,
d = 2;
printf("n1 = %d | n2 = %d | d = %d\n\n", n1, n2, d);
printf("Prime Numbers between %d and %d are: \n", n1, n2);
primeNumberList(n1, n2, d);
printf("\n\n");
return 0;
}
int primeNumberList(int n, int m, int z) {
int notPrime = 0;
if (n <= 1) {
primeNumberList(n + 1, m, z);
} else
if (n < m) {
if (z <= n / 2) {
if (n % z == 0) {
notPrime = 1;
z = 2;
} else {
primeNumberList(n, m, z + 1);
}
}
if (notPrime == 0) {
printf("%d ", n);
}
primeNumberList(n + 1, m, z);
}
}
What happens when I run this, is that after it's gone through all the numbers up to the limit (in the function it's m (n2 in main)) it won't break the recursion, but somehow manage to subtract numbers from n, and starts printing some other numbers that are not prime numbers.
When I run it in debug, it seems to be looping at the end, but there's nothing there to loop... I've tried adding a return 0; or even a printf with some text, but it ignores it completely.
Can anyone see what I've done wrong here? Why doesn't it stop when n < m?
I found your problem. You have the potential to make two recursive calls for each time you call primeNumberList.
After you return from primeNumberList(n, m, z+1); (under the innermost else) you still can go on to print a prime and do a call to primeNumberList(n+1, m, z);. This is not the behavior you want, you want to return directly after this inner else call.
So simply add a return before each of your calls to primeNumberList (primeNumberList(x); becomes return primeNumberList(x);) and also a return 0 at the end of this function (this last return is just to make the compiler happy).
Try something cleaner: defining a separate isPrime function and calling it.
http://www.cquestions.com/2011/08/prime-number-program-in-c-using.html
int isPrime(int num,int i){
if(i==1){
return 1;
}else{
if(num%i==0)
return 0;
else
isPrime(num,i-1);
}
}
Your recursive function exit criteria is not right.
When you you call the recursive function, it winds up, then down. When I run your code through step by step, As it is winding up, I get the complete list of primes, as following:
Then as it continues and the following digits, are printed:
Your question: Why doesn't it stop when n < m?
Because as you start unwinding, the values stored in the value n also start unwinding down through the iterations of the recursions that have been called, allowing execution flow to stay in the loop.
Further more, if unwind brings execution flow to a point that passes the printf("%d ", n); statement, the value for n, whatever it is at that unwind iteration, will be printed out.
One way way to leave without printing anything beyond n == 10 is to create a bypass variable, and use it as a criteria for printing:
static done = 0;
Then set done to 1 when you do not want to print any more values as it is unwinding.
Here is a modified function that will do this:
int primeNumberList(int n, int m, int z) {
int notPrime = 0;
static done = 0;//add a bypass variable, init to zero
if (n <= 1) {
primeNumberList(n + 1, m, z);
}
else
{
if(n == 10)
{
done = 1; //at this point all primes (except 1) are printed
//so set done to 1
}
if (n < m)
{
if (z <= n / 2)
{
if (n % z == 0)
{
notPrime = 1;
z = 2;
}
else
{
primeNumberList(n, m, z + 1);
}
}
if ((notPrime == 0) && (!done)) //test done before printing
{
printf("%d ", n);
}
primeNumberList(n + 1, m, z);
}
}
return 0;//add this return statement
}
Related
Basically, its printing only one instance when it happens, and i don't understand why, maybe has something to do with the code reseting every time and starting the variable at 0 again, and i got another question if someone can help me with, i have to return both values when its odd and even, like how many digits are even and odd at the same time, i'm having a little trouble figuring out how to do it
#include <stdio.h>
int digits(int n)
// function that checks if the given value is odd or even, and then add
// + 1 if it's even, or odd, it's supposed to return the value of the quantity
// of digits of the number given by the main function
{
int r;
int odd = 0;
int even = 0;
r = n % 10;
if (r % 2 == 0) // check if given number is even
{
even = even + 1;
}
if (r % 2 != 0) // check if its odd
{
odd = odd + 1;
}
if (n != 0) {
digits(n / 10); // supposed to reset function if n!=0 dividing
// it by 10
}
if (n == 0) { return odd; }
}
int
main() // main function that sends a number to the recursive function
{
int n;
printf("type number in:\n ");
scanf("%d", &n);
printf("%d\n", digits(n));
}
odd and even variables are local in your code, so they are initialized by zero every time.
I think they should be declared at caller of the recursive function, or be declared as global variables.
#include <stdio.h>
void digits(int n, int *even, int *odd)//function
{
int r;
r = n % 10;
if (r % 2 == 0)//check if given number is even
{
*even = *even + 1;
}
else //otherwise, its odd
{
*odd = *odd + 1;
}
n /= 10;
if (n != 0)
{
digits(n, even, odd);//supposed to reset function if n!=0 dividing it by 10
}
}
int main()
{
int n, even = 0, odd = 0;
printf("type number in:\n ");
scanf("%d", &n);
digits(n, &even, &odd);
printf("even: %d\n", even);
printf("odd: %d\n", odd);
return 0;
}
Maybe I found the problem you are facing. You you initialized you odd and even variable as zero. every time you call the function it redeclares their value to zero again. You can use pointer caller or use those as your global variable so that every time they don't repeat their initial values again.
Implementing a function that counts the number of odd and even digits in a number, is not to be done using recursive. That is simply a wrong design choice.
But I assume that it's part of your assignment to use recursion so ... okay.
You want a function that can return two values. Well, in C you can't!! C only allows one return value. So you need another approach. The typical solution is to pass pointers to variables where the result is to be stored.
Here is the code:
void count_odd_even(const int n, int *even, int *odd)
{
if (n == 0) return;
if (((n % 10) % 2) == 1)
{
*odd += 1;
}
else
{
*even += 1;
}
count_odd_even(n/10, even, odd);
}
And call it like
int odd = 0;
int even = 0;
count_odd_even(1234567, &even, &odd);
Given below is the code for finding prime numbers between the interval entered by the user.
#include <stdio.h>
int main() {
int n1, n2, i, flag;
scanf("%d%d", &n1, &n2);
for (i = n1; i <= n2; i++) {
flag = prime(i);
if (flag == 1)
printf("\n%d", i);
}
return 0;
}
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
See in this prime function, when we observe the iteration of for loop if value of n is 15 then it will look like this:
for (j = 2; j <= 15 / 2; j++)
I agree this is true. Because 2<7.
Since the condition is true we will enter inside the for loop:
if(n%j==0){
flag=0;
break;
}
Now, since n=15 and j=2, value of n%j=1, which is obviously not equals to 0; so if loop will not be executed and the prime function will return flag =1; and the main function will print 15 as a prime.
But, after Executing the program the code is showing the correct results: it's not showing 15 as a prime.
So can anyone please help me understand the logic behind this code? (Actually I want to understand how this code is eliminating non-prime odd numbers.)
You checked the execution for j==2, but since there is a for loop for(j=2;j<=n/2;j++). The code will run from j=2 to j=n/2. So, if you consider all the iterations, you will realize that the function is working fine.
The first if statement is false, so for j==2, the program won't go inside the if statement.
The loop will iterate for the next value of j, which is 3. Since 15%3 == 0, the program will execute the statements within the if statement and return that 15 is not a prime number.
for(j=2;j<=n/2;j++){
if(n%j==0){
flag=0;
break;
}
}
In the case of n=15, the loop starts at i=2, the test i<=n/2 is true because 2<=7, then 15%2 is 1, hence the loop proceeds and i is incremented to 3, the loop test is true again because 3<=7 but 15%3 is 0 so flag is set to 0 and returned.
Note these remarks:
the code does not have a recursive function. You merely call a function prime() to check each number in the interval for primality.
prime() should be defined or at least declared before the main() function that calls it.
you can test the return value of prime(i) directly. No need for a flag variable.
for prime numbers, the loop will iterate way too far: you can change the test to j <= n / j to stop at the square root of n.
you can return directly from the loop body.
you should output the newline after the number.
Here is a modified version:
#include <stdio.h>
int isprime(int n) {
int j;
for (j = 2; j <= n / j; j++) {
if (n % j == 0)
return 0;
}
return 1;
}
int main() {
int n1, n2, i;
if (scanf("%d%d", &n1, &n2) != 2)
return 1;
for (i = n1; i <= n2; i++) {
if (isprime(i))
printf("%d\n", i);
}
return 0;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Well this function doesn't need to handle specially nonprime numbers, based on the fact that if we can divide the number n by something (be prime or not), the number will be compose. What it does it to get out of the loop (with flag changed into 0) as soon as it finds a number j that divides n.
There's an extra optimization, that can save you a lot of time, that consists on calculating numbers until the integer rounded down square root of n as, if you can divide the number by a number that is greater than the square root, for sure there will be a number that is less than the square root that also divides n (the result of dividing the original number by the first will give you a number that is lower than the square root) so you only need to go up until the square root. While calculating the square root can be tedious (there's a library function, but let's go on), it is only done once, so it is a good point to use it. Also, you can initialy try dividing the number by two, and then skip all the even numbers, by adding 2 to j, instead of incrementing.
#include <math.h>
/* ... */
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE; /* all these numbers are prime */
if (n % 2 == 0) return FALSE; /* all these numbers are not */
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n); /* see below */
for (j = 3; j <= square_root; j += 2) { /* go two by two */
if (n % j == 0)
return FALSE;
}
/* if we reach here, all tests failed, so the number must be prime */
return TRUE;
}
While there's a sqrt() function in <math.h>, I recommend you to write an integer version of the square root routine (you can devise it easily) so you don't need to calculate it in full precision (just to integer precision).
/* the idea of this algorithm is that we have two numbers between 1 and n,
* the greater being the arithmetic mean between the previous two, while
* the lower is the result of dividing the original n by the arithmetic mean.
* it is sure than if we select the arithmetic mean, the number will be
* between the previous ones, and if I divide n by a number that is lower,
* the quotient will be higher than the original number. By the way, the
* arithmetic mean is always bigger than the square root, so the quotient
* will be smaller. At each step, both numbers are closer to each other, and
* so, the smaller is closer to the result of dividing n by itself (and this
* is the square root!)
*/
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
/* return the smaller of the two */
return arith;
}
so, your program would be:
#include <stdio.h>
#define FALSE (0)
#define TRUE (!FALSE)
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
return arith;
}
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE;
if (n % 2 == 0) return FALSE;
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n);
for (j = 3; j <= square_root; j += 2) {
if (n % j == 0) {
return FALSE;
}
}
return TRUE;
}
int main() {
unsigned n1, n2, i;
scanf("%u%u", &n1, &n2);
for (i = n1; i <= n2; i++) {
if (prime(i))
printf("%u\n", i);
}
return 0;
}
If you try your version against this one, with values like 2000000000 and 2000000100 you will see how this is saving a lot of calculations (indeed, for the cases below, the case of considering only the odd numbers when going throug the loop will take out of it half the numbers ---this is 1000000000 tests---, but the square root will reduce the number of tests to its square root ---only around 40000 tests--- for each number!!!).
$ primes
2000000000 2000000100
2000000011
2000000033
2000000063
2000000087
2000000089
2000000099
$ _
Your version takes (on my system) this execution time:
$ echo 2000000000 2000100000 | time primes0 >/dev/null
3.09user 0.00system 0:03.09elapsed 99%CPU (0avgtext+0avgdata 1468maxresident)k
0inputs+0outputs (0major+69minor)pagefaults 0swaps
$ _
while the version proposed takes:
$ echo 2000000000 2000100000 | time primes >/dev/null
0.78user 0.00system 0:00.78elapsed 99%CPU (0avgtext+0avgdata 1572maxresident)k
0inputs+0outputs (0major+72minor)pagefaults 0swaps
$ _
I'm working on a lab for my C class and we are doing recursions and functions. I was looking for help and tried doing this that should get me the answer but when I type in my inputs, it only returns a segmentation fault.
I've tried rearranging the positions of the variables and functions and even the int/float types, but nothing seems to work and I always get the same error.
#include <stdio.h>
float power(float, int);
int main(void)
{
float n;
int k;
printf("Please enter n = ");
scanf("%f", &n);
printf("Please enter k = ");
scanf("%d", &k);
printf("Sum = %f", power(n, k));
return 0;
}
float power(float n, int k)
{
return n * power(n, k - 1);
}
I expected 3 ** 3 is 27 but instead get Segmentation Fault :(
Your recursion is calling itself infinitely - it does power(3, 3), power(3, 2), power(3, 1), power(3, 0), power(3, -1)... and so on.
Any number to the power of 0 is 1.0 - that's your base case, so that's where you return.
For a bit of error catching, you can also see if the power passed in is too small to be valid.
float power(float n, int k)
{
if(k > 0) {
return n * power(n, k - 1);
}
if(k == 0) {
return 1.0;
}
return 1.0 / power(n, -k);
}
You need to admit that recursion is wrong and broken, and should never be used.
For example, if you add something to stop the recursion (e.g. if(k == 0) return 1;) it will still cause segmentation faults for large values of k (e.g. if you do x = power(1.0, INT_MAX)).
For this case, it's trivial to convert it into a simple loop; like:
float power(float n, int k) {
float result = 1.0;
while(k > 0) {
result *= n;
k--;
}
return result;
}
However even though this is no longer horribly bad because of recursion, it's still not good because the algorithm is inefficient (especially for large values of k).
A more efficient algorithm is something like:
float power(float n, unsigned int k) {
float result = 1.0;
while(k > 0) {
if( (k & 1) != 0) {
result *= n;
}
k >>= 1;
n *= n;
}
return result;
}
For this version, with a large value of k like 50000 the loop will only be executed 16 times instead of 49999 times, which makes it significantly faster.
Of course you can make the efficient version bad again by using recursion, like this:
float power(float n, unsigned int k) {
float result = 1.0;
if(k > 1) {
result = power(n*n, k >> 1);
}
if( (k & 1) != 0) {
result *= n;
}
return result;
}
In this case, (instead of being significantly more efficient because it loops a lot less) it will be significantly more efficient because it recurses a lot less (and then slightly less efficient because recursion sucks); and "recurses a lot less" is important because it means that it's far less likely that large values of k will make it crash.
I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}
I am writing a program to calculate the factorial of a number. I am using recursion to solve this problem. The problem I am running into is that once I reach number 13, it will throw garbage numbers because of INT's limit. What I want to do is implement a way to catch the error when it happens (without hard cording that at x=13 it has to stop, but rather by the output). This is my attempt:
#include <stdio.h>
int factorial( int n)
{
printf("Processing factorial( %d )\n", n);
if (n <= 1)
{
printf("Reached base case, returning...\n");
return 1;
}
else
{
int counter = n * factorial(n-1); //Recursion to multiply the lesser numbers
printf("Receiving results of factorial( %d ) = %d * %d! = %d\n", n, n, (n-1), counter);
if( counter/n != factorial(n-2) ) //my attempt at catching the wrong output
{
printf("This factorial is too high for this program ");
return factorial(n-1);
}
return counter;
printf("Doing recursion by calling factorial (%d -1)\n", n);
}
}
int main()
{
factorial(15);
}
The problem with this is that the program now never terminates. It keeps on looping and throwing me random results.
Since I cannot answer my own question, I will edit with my solution:
int jFactorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
int counter = n *jFactorial(n-1);
return counter;
}
}
void check( int n)
{
int x = 1;
for(x = 1; x < n+1; x++)
{
int result = jFactorial(x);
int prev = jFactorial(x-1);
if (((result/x) != prev) || result == 0 )
{
printf("The number %d makes function overflow \n", x);
}
else
{
printf("Result for %d is %d \n", x, result);
}
}
}
A better way to do it:
if (n <= 1) {
return 1;
} else {
int prev_fact = factorial(n - 1);
if (INT_MAX / prev_fact < n) { /* prev_fact * n will overflow */
printf("Result too big");
return prev_fact;
} else {
return prev_fact * n;
}
}
Uses a more accurate check (I hope) for whether the multiplication will overflow, and doesn't add any more calls to factorial.
Update
After looking more closely, turns out I missed the fact that gmp is also implemented for C. Here is the solution in C
I've been able to run it on my macbook pro, using homebrew to install gmp (brew isntall gmp)
#include <gmp.h>
#include <stdio.h>
void factorial(mpz_t ret, unsigned n) {
if (n <= 1) {
mpz_set_ui(ret, 1);//Set the value to 1
} else {
//multiply (n-1)! with n
mpz_t ret_intermediate;
mpz_init (ret_intermediate);//Initializes to zero
factorial(ret_intermediate, n-1);
mpz_mul_ui(ret, ret_intermediate, n);
}
return;
}
int main(){
mpz_t result;
mpz_init (result);
factorial(result, 100);
char * str_result = mpz_get_str(NULL, 10, result);
printf("%s\n", str_result);
return 0;
}
Original Answer
After quick googling, I found the following solution. Note this is a C++ solution. I briefly descirbe how you could do the same thing in ANSI C at the bottom.
Big numbers library in c++
https://gmplib.org/ This c++ library can work on numbers arbitrarily large.
Checkout https://gmplib.org/manual/C_002b_002b-Interface-General.html
The whole code could look something like....
#include <gmpxx.h>
#include <iostream>
mpz_class factorial(unsigned n) {
if (n <= 1) return mpz_class(1);
return mpz_class(n) * factorial(n-1);
}
int main(){
mpz_class result = factorial(100);
std::string str_result = result.get_str();
std::cout << str_result << std::endl;
return 0;
}
The ANSI C Version
You could implement the same thing using ansi C, with a structure to hold expanding list of numbers(using linked-list or any other expandable arraylist containers), and you'd only need to implement three methods... initialize, multiply and convert to string.