Check if binary search tree contains more evens numbers than odds - c

I want to implement a function to check if a BST (of int values) contains more odds it should return 2, if it contains more evens return 1 and 0 otherwise - recursively.
I was trying to create help function with inputs of even and odd counter but the function returns wrong output.
My code:
int evenOdd(Tnode* root) {
if (root == NULL)
return 0 ;
return eVenOddHelp(root , 0 , 0) ;
}
int eVenOddHelp(Tnode* root , int even , int odd) {
if (root == NULL) {
if (even > odd)
return 1 ;
else if (odd > even)
return 2 ;
return 0 ;
}
else {
if (root->data % 2 == 0) {
eVenOddHelp(root->left , even + 1 , odd) ;
eVenOddHelp(root->right , even + 1 , odd) ;
}
else {
eVenOddHelp(root->left , even , odd + 1) ;
eVenOddHelp(root->right , even , odd + 1) ;
}
}
}

IMO the easiest way is to use the return value, if return positive there are more evens, if negative there are more odds, 0 otherwise:
int evenOdd(Tnode* root) {
int result = eVenOddHelp(root);
if(result > 1) return 1; // More evens
else if(result == 0) return 0; // the same
else return 2; // More odds
}
int eVenOddHelp(Tnode* root) {
if (root != NULL) {
int isEven = (root->data % 2 == 0) ? 1 : -1;
return eVenOddHelp(root->left) + eVenOddHelp(root->right) + isEven;
}
return 0;
}
Comparing like this:
if (root == NULL) {
if (even > odd)
return 1 ;
else if (odd > even)
return 2 ;
return 0 ;
}
Will produce wrong values because there is several times where the root == NULL is true, you will comparing evens and odds in different subtrees. And not at the end of the entire tree.

There's an easier way to do this by using counters passed in as mutable pointers:
void modCounter(Tnode* node, int* even, int* odd) {
if ((node->data % 2) == 0) {
(*even)++;
}
else {
(*odd)++;
}
if (node->left) {
modCounter(node->left, even, odd);
}
if (node->right) {
modCounter(node->right, even, odd);
}
}
Note that it just alters the pointed values, so you call it like this:
int evenOdd(Tnode* root) {
if (root == NULL)
return 0;
int even = 0;
int odd = 0;
modCounter(root, &even, &odd);
if (even > odd) {
return 1;
}
if (odd > even) {
return 2;
}
return 0;
}
To use a more C-based approach you could even pass in an array of two int values, as in:
void modCounter(Tnode* node, int* counters, int mod) {
++counters[node->data % mod];
// ...
}
Where you call it like this:
int counters[2];
modCounter(root, &counters[0], 2);

Related

Shorthand for return function

The code below demonstrate in C language so anyone could easily understand the need. But I use to know many other programming language as well.
Running the code as [1] will give me an error in some programming language & some programming language give warning
[1]:
int get_value(int number) {
if (number == 0) { return 12; }
else if (number == 1) { return 21; }
// return;
}
So, I must code something like [2] to clear the error/warning
[2]:
int get_value(int number) {
int ret = 0;
if (number == 0) { ret = 12; }
else if (number == 1) { ret = 21; }
return ret;
}
QUESTION:
How do I shorthanded the code in [2] as the code in [1] without any error/warning. And the expected code as short as [1]
imagine that the parameter number = 3
then what would you return ?
you can simply write at the end of the function return 0;
so:
int get_value(int number) {
if (number == 0) { return 12; }
else if (number == 1) { return = 21; }
return 0;
}
so you should think of different values of the parameter called number.
In the first code snippet compilers issue a message because the function returns nothing if number is not equal to 0 or 1.
You could write for example
int get_value(int number) {
if (number == 0) { return 12; }
else if (number == 1) { return 21; }
else { return 0; }
}
Or you could write
int get_value(int number) {
int ret[] = { 12, 21 };
if ( 0 <= number && number <= 1 ) { return ret[number]; }
else { return 0; }
}
Or you could use the conditional operator like for example
int get_value(int number) {
return number == 0 ? 12 : number == 1 ? 21 : 0;
}
By universal convention (including in C), 0 is regarded as false and all other values are true.
So it may make sense to code:
int get_value(int number) {
if (number == 0) {
return 12;
}
return 21;
}
As others point out you don't appear to have defined a return value for all possible inputs. It maybe that your function is only ever called with 0 or 1. If that's the case the parameter name number is poorly chosen.
But "defensive programming" says you should deal with all cases.
You either map all inputs into legitimate return values or introduce an error handler or trap.
Here's an error trap version using the assert() macro.
#include <assert.h>
int get_value(int number) {
assert((number==0)||(number==1));
if (number == 0) {
return 12;
}
return 21;
}
If the condition provided to the assert() macro is false, execution ends printing a diagnostic message.
These warnings/errors arise because your function declaration states that it should always return an int:
int get_value(int number) {
In the first version of your code, it would not do that for numbers other than 0 or 1:
int get_value(int number) {
if (number == 0) { return 12; }
else if (number == 1) { return 21; }
}
For example, what would this do if you called it with number set to 2?
The second example always returns an int, thus honouring the "contract" defined by the function declaration:
int get_value(int number) {
if (number == 0) { return 12; }
else if (number == 1) { return 21; }
return 0;
}
In some (non-C) programming languages -- such as Ruby or Javascript -- the former would be allowed due to nil/None/undefined being used as an implicit return value, but this is because function declarations do not specify that they "must" return an int value in those languages:
// Javascript example:
function get_value(number) {
if (number == 0) { return 12; }
else if (number == 1) { return 21; }
}
get_value(2) // Returns `undefined`.
How do I shorthanded the code..??
You can study the problem, and use branchless programming to give you the results that you want.
#include <stdio.h>
int get_value( unsigned int n ) {
return (n<2)*(0x2AC>>(5*n))&0x1F;
}
int main() {
for( int i = 0; i < 10; i++ )
printf( "%i: %2d %2d\n", i, get_value( i ), (i<2)*(0x2AC>>(5*i))&0x1F );
return 0;
}
0: 12 12
1: 21 21
2: 0 0
3: 0 0
4: 0 0
5: 0 0
6: 0 0
7: 0 0
8: 0 0
9: 0 0

Recursive function in C to determine if digits of an integer are sorted ascending, descending or neither

I need to write a recursive function that returns 1 if digits of a whole number are ascending (left to right), return -1 if descending or return 0 if neither.
My solution attempt returns 0 every time and I know why but I don't know how to get around it.
Here's my code:
#include <stdio.h>
int check_order(int n)
{
if (n % 10 > n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return 1;
}
}
else if (n % 10 < n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return -1;
}
}
else
{
return 0;
}
}
int main()
{
int n;
printf("enter a whole number (n > 9):");
scanf_s("%d", &n);
printf("function returned: %d\n", check_order(n));
}
Here's a simple recursion:
int f(int n){
if (n < 10)
return 0;
int dr = n % 10; // rightmost digit
n = n / 10;
int dl = n % 10; // second digit from the right
int curr = dl < dr ? 1 : -1; // current comparison
if (dl == dr) curr = 0; // keep strict order
if (n < 10)
return curr;
return curr == f(n) ? curr : 0; // are the comparisons consistent?
}
Explain your algorithm?
Suppose you use the following:
You are given a number.
You need to turn that number into a sequence of digits.
If you are given a number, you can convert that number to a sequence of digits.
If you are given a sequence of digits, use
that.
Compare each pair of digits -> ascending, descending, or neither.
Combine the results from each pair, sequentially/recursively.
We can use a string to make the digit comparisons easier, and accept very long sequences of digits.
We can use an enum(erated) type to represent the ordering.
How do you combine the results? Define a function that combines the order of two adjacent, overlapping pairs, then you can combine results.
#include <stdio.h>
#include <string.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t;
order_t pair_order(int a, int b) {
if( a < b ) return ascending;
if( a > b ) return descending;
return other;
}
//strict (increasing/decreasing)
order_t strict_order( order_t x, order_t y ) {
if( x == y ) return x;
return other;
}
//monotone (increasing/decreasing)
order_t monotone_order( order_t x, order_t y ) {
if( x == y ) return x;
if( other == x ) return y;
if( other == y ) return x;
return other;
}
order_t check_order( char* p, int remain ) {
//printf("p:%s\n",p); //uncomment to watch progress
if( remain<2 ) return other;
if( remain==2 ) return pair_order(p[0], p[1]);
return strict_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
//return monotone_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
}
char* order_name[] = {
"descending",
"other",
"ascending"
""
};
int main()
{
char line[666] = "none";
while ( strlen(line) > 0 ) {
printf("enter a number (at least 2 digits):");
fgets(stdin,line,sizeof(line)-1);
if( strlen(line) > 0 && line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = '\0';
order_t order = check_order(line);
printf("function returned: (%d)%s\n", order, order_name[order+1]);
}
}
I think you were started on the right track but need to flesh out your code more. My solution borrows on that of #ChuckCottrill as I like his enum but I don't like that he doesn't play the ball as it lays (i.e. converts to a string instead of dealing with the int.) I also borrow the nice test examples of #ggorlen but I don't like that solution either as it can take multiple passes through the number to figure out the answer when only one pass should be needed:
#include <stdio.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t; // a la #ChuckCottrill
order_t check_order(int n)
{
if (n > 9) {
int right = n % 10;
int left = n / 10 % 10;
if (right > left) {
n /= 10;
if (n > 9) {
return (ascending == check_order(n)) ? ascending : other;
}
return ascending;
}
if (right < left) {
n /= 10;
if (n > 9) {
return (descending == check_order(n)) ? descending : other;
}
return descending;
}
}
return other;
}
int main() { // a la #ggorlen
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
}
OUTPUT
> ./a.out
12345: 1
54321: -1
54323: 0
454321: 0
1: 0
12: 1
21: -1
>
A version that works for any length since it takes the string as parameter.
And feeding the recursive function with previous status (ascending or descending) allows for some shorter code and less functions.
int check_order(char *str, int index, int previous) {
char current = str[index]; // char at index
char next = str[index+1]; // char at index+1
if (current == 0 || next == 0) {
return previous; // End of string
}
// Ascending or descending?
int status = next > current ? 1 : (next < current ? -1 : 0);
if (status == 0 || index > 0 && status != previous) {
// If neither -1/1 nor status == previous (while not initial call)
return 0;
}
return check_order(str, index+1, status); // Check from next index
}
The main function must ensure the string is at least 2 chars
int main(int argc, char **argv) {
char *str = *++argv;
// Some optional checks on str here... (like this is a number)
int status = 0; // Default value if string length < 2
if (strlen(str) >= 2) {
status = check_order(str, 0, 0);
}
printf("Check order for %s is %d\n", str, status);
return 0;
}
Code after a return statement like this is unreachable:
return check_order(n / 10);
if (n == 0)
{
return -1;
}
Beyond this, you're on the right track of checking the current digit against the next digit, but I don't see a clear base case (when n < 10, that is, a single digit).
Trying to check ascending and descending in one recursive function is difficult to manage. In particular, communicating state between stack frames and determining which cases are still valid at a given call suggests that the return value is overworked.
To save having to return a struct or use an enum or magic numbers as flags, I'd write two general helper functions, ascending_digits and descending_digits.
#include <stdbool.h>
#include <stdio.h>
bool ascending_digits(int n) {
if (n < 10) return true;
if (n % 10 < n / 10 % 10) return false;
return ascending_digits(n / 10);
}
bool descending_digits(int n) {
if (n < 10) return true;
if (n % 10 > n / 10 % 10) return false;
return descending_digits(n / 10);
}
int check_order(int n) {
if (ascending_digits(n)) return 1;
if (descending_digits(n)) return -1;
return 0;
}
int main() {
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
return 0;
}
Output:
12345: 1
54321: -1
54323: 0
454321: 0
1: 1
12: 1
21: -1
Not only are these functions easier to understand and maintain individually, they're also more reusable than if they were inseparably tied together.
This doesn't handle negative numbers--you could apply abs and go from there if you want. Same goes for handling equal values; this implementation accepts numbers such as 1223 but you could use <= to enforce strict ordering.

Understanding calling one function inside another C

I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}

Recursive function for counting divisible digits in C

I need to write a recursive function which accepts a number, and it needs to check whether each number is divisible with the previous number. For example, if the input is 63542, result should be 2, while only 6 is divisible by 3, and 4 is divisible by 2. These are the only numbers that are divisible with the their previous number. I have the following code, but it returns every time one more. For the above example it should return 2 but it returns 3.
#include <stdio.h>
int deliv(int num)
{
int temp = num%100;
int counter = 0;
if(num == 0)
{
return 0;
}
else if((temp/10)%(num%10) == 0)
{
counter++;
return counter + deliv(num/10);
}
else return counter + deliv(num/10);
}
int main()
{
int result = deliv(63542);
printf("%d\n", result);
return 0;
}
You want to change your test condition from if(num == 0) to if(num < 10 ) because if num is a single digit number, temp becomes 0 since temp = num/10, which is divisible by num%10.
Also, add this condition to avoid crashing when two consecutive digits are 0.
if(num < 10)
{
return 0;
}
//To avoid crash due to 2 zeroes
else if(temp==0)
{
return counter + deliv(num/10);
}
else if((temp/10)%(num%10) == 0)
{
counter++;
return counter + deliv(num/10);
}
else return counter + deliv(num/10);

how to make loop in this case?

I need compute the first 100 prime numbers, but in the output i got "9" and other in my numbers....................... i want compute the first 100 prime numbers
{
bool prime; int start, new, kor,k, i,gg;
start=1;
k=1 ;
gg=0;
do
{
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
if (start > 2) {
if ((new % 2) == 0)
new--;
do {
prime = true;
kor=sqrt(new);
new+=2;
for (i=3;prime&& (i<=kor); i+=2) {
if (new % i == 0)
prime=false;}
} while (!prime) ;
}
gg++;
printf("%d->%d\n",gg, new);
k++;
start++;
continue;
}
while (k<101);
}
With
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
you have special cases the first and second numbers.
Next time round the do...while loop we skip the for loop because kor is 1, thereby printing 5. Which we didn't check, so perhaps we just got lucky. Smells like we don't check far enough.
Next time, after
kor=sqrt(new1); new1+=2;
kor is 2, so again we don't do the for loop, and print 7. Next time we have the same situation. kor is still 2 so you get 9.
I think if you switch the new+=2 to before the kor=sqrt(1); it will work.
Once you are in this part, you don't need to check if something is even, since you always add 2 to an odd number.
BTW Why does it say continue as the last thing in the loop?
This might be better (I took the liberty of putting it in a function):
void find_primes()
{
bool prime; int start, new, kor,k, i,gg;
start=1; k=1 ;gg=0;
do
{
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
if (start > 2) {
do {
prime = true;
new+=2;
kor=sqrt(new);
for (i=3;prime&& (i<=kor); i+=2) {
if (new % i == 0)
prime=false;
}
}
while (!prime) ;
}
gg++; printf("%d->%d\n",gg, new);
k++;
start++;
}
while (k<101);
}
I don't know what language you're programming in, so I'm taking a guess at this (I can't comment yet)-
Are you getting all odd numbers as output in your answer? 9, 11, 13, 15...
It seems that you are printing out all values of 'new', regardless of whether prime is true or not. Maybe you should put a
if (prime) {
printf("%d->%d\n",gg, new);
}
there
here is an example program from:
http://www.programmingsimplified.com/c/source-code/c-program-for-prime-number
note: 1 is not a prime number, see:
http://primes.utm.edu/notes/faq/one.html
#include<stdio.h>
int main()
{
int n, i = 3, count, c;
printf("Enter the number of prime numbers required\n");
scanf("%d",&n);
if ( n >= 1 )
{
printf("First %d prime numbers are :\n",n);
printf("2\n");
}
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= (i - 1) ; c++ )
{
if ( i%c == 0 ) break;
}
if ( c == i )
{
printf("%d\n",i);
count++;
}
i++;
}
return 0;
}

Resources