i have this function that when i start it prints only even numbers of the entered parameter can anyone explain to me what exactly happens in this function and how it ends up getting the even numbers
#include <stdio.h>
int what(int x){
if (x == 0)
return 0;
if (x % 2 == 0)
return what(x / 10) * 10 + x % 10;
return what(x / 10);
}
int main(){
printf("%d\n",what(145825));
return 0;
}
output
482
Here's what happens:
The what() function starts with the rightmost digit (= the whole number modulo 10) and then recurses into the rest of the digits by throwing away the rightmost digit (integer division by 10 throws away the right decimal digit).
If the right digit is even it is appended to the result of the recursion by multiplying it by 10 (making space for the extra digit on the right) and adding this digit (= the whole number modulo 10).
If the right digit is odd nothing is added to the result of the recursion.
Recursion stops when there are no more digits.
A good way to figure out to make recursion is to make a table that keeps track of what happens during each step, but of course a debugger is always the best way to really check what happens.
The following table is what happens each time what() is called:
x recursive x result even? returns
------ ----------- ------ ------- -------
145825 14582 482 - 482
______/ \_____________
/ \
14582 1458 48 48*10+2= 482
1458 145 4 4*10+8= 48
145 14 4 - 4
14 1 0 0*10+4= 4
1 0 0 - 0
0 - - - 0
This question already has answers here:
How does XOR work in C to find a number occurring odd number of times?
(4 answers)
Closed 6 years ago.
Trying to understand the XOR importance, I found this code:
Given a set of numbers where all elements occur even number of times except one number, find the odd occurring number
But I can't visualize it.
How does the XOR bitwise operator roll out the odd element?
// Function to return the only odd occurring element
int findOdd(int arr[], int n) {
int res = 0, i;
for (i = 0; i < n; i++)
res ^= arr[i];
return res;
}
int main(void) {
int arr[] = { 12, 12, 14, 90, 14, 14, 14 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("The odd occurring element is %d\n", findOdd(arr, n));
return 0;
}
Output: The odd occurring element is 90
The way I read it you are really asking two questions:
What is the importance of XOR?
How does XOR help find the odd occurrence of a number in a series?
In order to understand question (2), one must understand question (1). Understanding question (1) requires an adequate introduction to the XOR logic and the properties it has.
What is the importance of XOR?
Definition: The output of an XOR operation is TRUE if and only if the number of TRUE inputs are odd. Commonly referred to as "one or the other, but not both"
This is captured by the following truth table:
XOR Truth Table
Using the truth table it is trivial to derive the following properties:
A ^ 0 = A (The output follows the variable input)
A ^ 1 = A' (The output is the negation of the variable input)
A ^ A = 0 (The output is always zero since both inputs are equal)
(A ^ B) ^ C = A ^ (B ^ C) (Associative Property)
A ^ B = B ^ A (Communative Property)
Now on to the importance of XOR, i.e., how these properties allow folks to make useful things. The first computing layer to note is the hardware layer. XOR gates are physical devices that have utility in many fundamental logic circuits, that fundamental utility being "odd occurrence detection". Some notable applications:
Half-Adders: The truth table for a half-adders SUM output is identical to the XOR gate. (Throw an AND gate in for the carry bit). Same thing for the Full-Adder, using XOR gates for the fundamental summation with some additional supporting gates.
Inverters: Using one input as a control and the other as the "input", the xor gate can be used to invert the input signal. The control bit can be used to pass the input through as well, acting as a buffer. In software, you use these circuits to toggle bits/bytes from one state to the other. Val = Val ^ 1 (Recall the second property above).
Comparators: The output of an XOR gate is 1 when the inputs are different, 0 when they are the same. This is the driving logic for the half-adder.
In addition to these circuits we can, at a hardware level, use XOR to check byte parity for Error Detection and Correction (EDAC) operations, swap register values (without a temp variable!), and recover corrupted/lost data from hard drives in a RAID system.
However, software junkies don't care about these circuits, they want to live in the land of abstractions that provide an easy way to use this hardware in a human intuitive way. Let there be code.
How does XOR help find the odd occurrence of a number in a series?
Even though the first comment to your question indicates the poster didn't understand your question, they inadvertently answered the question correctly, but I will explain further.
Let's break down what your findOdd() function is actually doing. The for loop is literally performing the following calculation:
Result = 0 ^ 12 ^ 12 ^ 14 ^ 90 ^ 14 ^ 14 ^ 14
Recall that XOR is communative, so after a little re-ordering the calculation becomes:
Result = 0 ^ 12 ^ 12 ^ 14 ^ 14 ^ 14 ^ 14 ^ 90
Using the property A ^ A = 0 and associativity, the XOR of 12 and 12 drops to 0 as does the XOR of the 14's, leaving:
Result = 0 ^ 0 ^ 0 ^ 0 ^ 90 = 0 ^ 90 = 90
In effect, the XOR forces even occurrences to become zero and A ^ 0 = A. Hope this verbose description of XOR was helpful in visualizing what is happening under the hood.
Binary XOR is the exclusive or operation, performed one bit at a time. It is equivalent to subtraction, modulo 2.
Here is the truth table for XOR:
a b a^b
1 0 1
1 1 0
0 0 0
0 1 1
As you can see, XOR sets a bit to 1 (true) when EITHER of the input bits is 1, but not both.
Now, consider this: what is 1 xor 1? From the truth table, you know it's zero.
And what is 1 xor 1 xor 1? Well, you know 1^1==0, so that leaves 0^1, which is 1.
So you have that xor'ing a 1 bit an even number of times will produce a zero, and an odd number of times will produce a 1.
Thus, if we take a ^ a ^ a, for some value of a, we get a result where all the 1 bits in the binary representation of a are set. (Which is to say, we get back 'a'.)
Whereas if we take a ^ a ^ a ^ a, for some value of a, we get a result where all the 1 bits in the binary representation of a are 0. (Which is to say, we get back 0.)
The one exception to this, of course, is 0. The binary representation for 0 has no set bits in it, so this approach will not indicate if the number of 0's was even or odd.
But I can't visualize it
Then you should step through the code one line at a time and keep an eye on res at each iteration through the loop.
Or just do it on paper -- write down the binary form of 12, i.e. 00001100, and then XOR that value with the next value, also 00001100, which gets you back to 00000000. Then XOR the next value with that, and so on. You might want to start with a short list of pairs of numbers, like {12, 12, 15, 15} and see what happens. Then try removing the last one, so you have {12, 12, 15} and see what you get. Then try reordering the list: {12, 15, 12}. Count the number of times that each bit gets flipped.
XOR means exclusive or, for each bit in the operands, the resulting bit is 1 if either corresponding bit of the operand is 1 but not both:
0 ^ 0 = 0, 1 ^ 0 = 1, 1 ^ 0 = 0 and 1 ^ 1 = 0.
Identical numbers cancel each other as x ^ x == 0 for all values. The final outcome of xoring all elements of the array is the number occurring an odd number of times, assuming there is only one.
This method works if all duplicate numbers but one occur an even number of times and if there is a single entry occurring an odd number of times.
XOR is commutative: a ^ b equals b ^ a.
XOR is associative: a ^ (b ^ c) equals (a ^ b) ^ c.
Together these two mean that you can arbitrarily reorder operands in a chain of XORs.
Furthermore:
0 is a neutral element: a ^ 0 equals a.
Every number is its own inverse: a ^ a equals 0.
In your code we're doing 12 ^ 12 ^ 14 ^ 90 ^ 14 ^ 14 ^ 14.
We can reorder this to (12 ^ 12) ^ (14 ^ 14) ^ (14 ^ 14) ^ 90, pairing up every element that occurs an even number of times with itself.
This simplifies to 0 ^ 0 ^ 0 ^ 90 (because all pairs of equal elements cancel each other out, giving 0), which reduces to just 90 (because XORing with 0 does nothing).
This is all about XOR operator.
^ is bit-wise XOR.
For example,
12^5 == 1100^0101 == (1^0)(1^1)(0^1)(0^1) == 1011
From the mathematical definition of XOR, the output is 1 iif the number of 1(s) in inputs is odd.
This case:
When a number occurs even number of times, the binary representation will also get two 1s or two 0s in each position, making the result going to 0.
Eg:
2^2^3 == (1^1^1)(0^0^1) == 11 == 3
i.e. 10 (2)
10 (2)
11 (3)
--------
11 (3)
========
5^7^5 == (1^1^1)(0^1^0)(1^1^1) == 111
101 (5)
111 (7)
101 (5)
---------
111 (7)
=========
Note that even occurring numbers have no affect here.
Given the following axioms:
x ^ x == 0
y ^ y ^ y == y
z ^ 0 == z
Then for example:
x ^ x ^ y ^ y ^ y == y
\___/ \_______/
0 ^ y == y
Also:
x ^ y == y ^ x
So the order of the operands does not matter.
The point is an odd number of occurrences of a value results in the value, while even results in zero, and a value xor'ed with zero is the value.
Consequently as the comment at the start of the code suggests, it works only when there is a single value with an odd number of occurrences and all other values occur an even number of times. Otherwise the result is simply the xor of all the odd occurring values, e.g.:
x ^ x ^ x ^ y == x ^ y
which is neither x nor y.
How to create a c code that receive int parameter n and return the value of this mathematical equation
f(n) = 3 * f(n - 1) + 4, where f(0) = 1
each time the program receive n , the program should start from the 0 to n which means in code (for loop) .
the problem here that i can't translate this into code , I'm stuck at the f(n-1) part , how can i make this work in c ?
Note. this code should be build only in basic C (no more the loops , no functions , in the void main etc) .
It's called recursion, and you have a base case where f(0) == 1, so just check if (n == 0) and return 1 or recurse
int f(int n)
{
if (n == 0)
return 1;
return 3 * f(n - 1) + 4;
}
An iterative solution is quite simple too, for example if f(5)
#include <stdio.h>
int
main(void)
{
int f;
int n;
f = 1;
for (n = 1 ; n <= 5 ; ++n)
f = 3 * f + 4;
printf("%d\n", f);
return 0;
}
A LRE (linear recurrence equation) can be converted into a matrix multiply. In this case:
F(0) = | 1 | (the current LRE value)
| 1 | (this is just copied, used for the + 4)
M = | 3 4 | (calculates LRE to new 1st number)
| 0 1 | (copies previous 2nd number to new 2nd number (the 1))
F(n) = M F(n-1) = matrixpower(M, n) F(0)
You can raise a matrix to the power n by using repeated squaring, sometimes called binary exponentiation. Example code for integer:
r = 1; /* result */
s = m; /* s = squares of integer m */
while(n){ /* while exponent != 0 */
if(n&1) /* if bit of exponent set */
r *= s; /* multiply by s */
s *= s; /* s = s squared */
n >>= 1; /* test next exponent bit */
}
For an unsigned 64 bit integer, the max value for n is 40, so the maximum number of loops would be 6, since 2^6 > 40.
If this expression was calculating f(n) = 3 f(n-1) + 4 modulo some prime number (like 1,000,000,007) for very large n, then the matrix method would be useful, but in this case, with a max value of n = 40, recursion or iteration is good enough and simpler.
Best will be to use recursion . Learn it online .
Its is very powerful method for solving problems. Classical one is to calculate factorials. Its is used widely in many algorithms like tree/graph traversal etc.
Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem.
Here you break you problem of size n into 3 instance of sub problem of size n-1 + a problem of constant size at each such step.
Recursion will stop at base case i.e. the trivial case here for n=0 the function or the smallest sub problem has value 1.
In some kinds of problems I often face this situation where I have a variable where I need to rearrange the digits, e.g., int e = 2385;. Let's suppose I don't know which number is stored there, but still I need to shift 2nd and 4th position. When I know variable's value I can simply do e = 2583, but when I don't know I simply can't solve the problem.
Another situation is when I have two values and want to use them to form another number i.e int a = 2, b = 1;, and I need to order them so that I will get a 21 or a 212. I mean, that's easy to do when I'm outputting data, I can simply do:
printf("%d%d\n",a,b);
printf("%d%d%d",a,b,a);
Problem is when I have to store this number in another variable. I don't know how to do that.
This can be broken into two tasks: (1) breaking up a number into pieces, and (2) combining pieces into a whole number.
To break up a number into pieces, use the division and modulus operators.
int num = 2385;
int a = num / 1000; // 2
int b = num / 100 % 10; // 3
int c = num / 10 % 10; // 8
int d = num / 1 % 10; // 5
The trick is to use division to remove the digits to the right, then modulus to keep only the rightmost digit. For example, to calculate the hundreds' place (b) we compute 2385 / 100, which is 23. 23 % 10 is the remainder when you divide 23 by 10. The remainder is 3.
To combine the pieces back into a number, do the opposite with multiplication and addition.
num = a * 1000 // 2000
+ d * 100 // + 500
+ c * 10 // + 80
+ b * 1; // + 3
// ----
// 2583
Notice how I switched d and b to swap those digits.
This program is for calculating students marks frequency
float value[50];
int group[11] = {0};
for (i = 0; i < 50; i++) {
scanf("%f",&value[i]); /* reading of values */
++group[(int)(value[i])/10)]; /* what does this line do.? */
}
This line:
++group[(int)(value[i]) / 10)];
Is the same as:
int flooredValue = (int)value[i]; //e.g. 3.5 becomes 3; 12.6 becomes 12
int groupIndex = flooredValue / 10; //division discarding the remainder
group[groupIndex] += 1;
What does it mean, though? Well here's how it ends up converting the values:
value[i] | groupIndex
----------+------------
3.5 | 0
12.6 | 1
18.6 | 1
23.1 | 2
57 | 5
94.6 | 9
100 | 10
So it ends up counting how many marks fall into each bucket of 10. Scores from 0 to 9.9999 fall in the "0" bucket, from 10 to 19.99999 in the "1" bucket, etc. Note the following, though:
value[i] | groupIndex
-----------+------------
-3.5 | -3
155.6 | 15
As it is now, your input could certainly be less than zero or over 100. If that happens, you're going to write into memory outside of the bounds of group. This will lead to very unpleasant behavior. Check either that the input value is in bounds or that the group index is in bounds before indexing into the group array.
++group[(int)(value[i])/10)];
lets divide this
1. (int)(value[i])/10)
for example value[i] is 51 it will result 5 as you are using casting to int.
2. ++group[5]; // is same as group[5] += 1;
pre incrementing value of group[5]
In sub-expression
(int)(value[i])/10)
value[i] is of type float, dividing it by 10 will give double value (after default promotion). But array subscripts should be of integer type, (int) is used to cast the return value of sub-expression to integer .
In expression
++group[(int)(value[i]) / 10)];
prefix ++ is used to pre-increment the array element group[(int)(value[i])/10)].