Having trouble understanding a portion of code (bit operation) - c++

I can't understand how to count number of 1's in binary representation.
I have my code, and I hope someone can explain it for me.
Code:
int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
Why while ? For example if i have 1011, it wouldn't stop at 0?
Why nr += x%2 ?
Why x/=2 ?!

First:
nr += x % 2;
Imagine x in binary:
...1001101
The Modulo operator returns the remainder from a / b.
Now the last bit of x is either a 0, in which case 2 will always go into x with 0 remainder, or a 1, in which case it returns a 1.
As you can see x % 2 will return (if the last bit is a one) a one, thus incrementing nr by one, or not, in which case nr is unchanged.
x /= 2;
This divides x by two, and because it is a integer, drops the remainder. What this means is is the binary was
....10
It will find out how many times 2 would go into it, in this case 1. It effectively drops the last digit of the binary number because in base 2 (binary) the number of times 2 goes into a number is just the same as 'shifting' everything down a space (This is a poor explanation, please ask if you need elaboration). This effectively 'iterates' through the binary number, allowing the line about to check the next bit.
This will iterate until the binary is just 1 and then half that, drop the remainder and x will equal 0,
while (x != 0)
in which case exit the loop, you have checked every bit.
Also:
'count`is possibly not the most descriptive name for a function, consider naming it something more descriptive of its purpose.
nr will always be a integer greater or equal to zero, so you should probably have the return type unsigned int

int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
This program basically gives the numbers of set bits in a given integer.
For instance, lets start with the example integer 11 ( binary representation - 1011).
First flow will enter the while loop and check for the number, if it is equal to zero.
while(11 != 0)
Since 11 is not equal to zero it enter the while loop and nr is assigned the value 1 (11%2 = 1).nr += 11%2;
Then it executes the second line inside the loop (x = x/2). This line of code assigns the value 5 (11/2 = 5 ) to x.
Once done with the body of the while loop, it then again checks if x ie 5 is equal to zero.
while( 5 != 0).
Since it is not the case,the flow goes inside the while loop for the second time and nr is assigned the value 2 ( 1+ 5%2).
After that the value of x is divided by 2 (x/2, 5/2 = 2 )and it assigns 2 to x.
Similarly in the next loop, while (2 != 0 ), nr adds (2 + 2%2), since 2%2 is 0, value of nr remains 2 and value of x is decreased to 1 (2/2) in the next line.
1 is not eqaul to 0 so it enters the while loop for the third time.
In the third execution of the while loop nr value is increased to 3 (2 + 1%2).
After that value of x is reduced to 0 ( x = 1/2 which is 0).
Since it fails the check (while x != 0), the flow comes out of the loop.
At the end the value of nr (Which is the number of bits set in a given integer) is returned to the calling function.
Best way to understand the flow of a program is executing the program through a debugger. I strongly suggest you to execute the program once through a debugger.It will help you to understand the flow completely.

Related

Has number unique digits?

I am currently trying to solve a problem set on codeforce where I need to check if an positive integer number has unique digits. My solutions includes a while loop and two for loops, which is quite a lot of for such an easy task.
I found a more elegant solution but I don't fully understand how the code works. I have commented it with my remarks. Could someone explain to me the second 2) and fifth 5) part?
int unique(long long int number){
/* 1) create array/list with 10 elements, the first element seen[0]
* is equal to zero */
char seen[10] = {0};
/* 2) what is the meaning of while(some random integer number)? I thought
* that the argument must be a statement that is either true or false. */
while (number) {
int digit = number % 10; // 3) get the last digit of the number
number /= 10; // 4) removes last digit of the number
/* 5) Could someone explain to me what seen[digit]++ does. And when its
* true or false? */
if (seen[digit]++)
return 0; /* not unique */
}
return 1; /* unique */
}
Of course I tried to figure out the fifth part on my own but
#include <iostream>
using namespace std;
int main(){
char seen[10] = {0};
cout << seen[7]++ << endl;
}
print outs nothing.
I'll go by parts:
2 ) The implicit conversion between a numeric type and bool returns false if the number is zero and true otherwise. You could read while(number) like while(number != 0)
5 ) This works the same way: seen[digit]++ is an expression with the same value as seen[digit] but that then increments its value (check how post-increment works). Therefore, the first time that digit is seen, seen[digit]++ has the value 0 (so the first time the condition is not met) and increments its value to 1 (so the second time the condition will be met, making the function return).
while(number) means the cycle will repeat until number is not zero. Non-zero number is equal to true
seen[digit]++ does following:
it return current value of seen[digit]. For the first time it will be zero - as no number met.
after returning current value - it increase value by one. So for the first call it will return 0 and the seen[digit] will become 1.
So for the second call it will return 1 - that mean this number already met, so it is not unique.
Q.1 what is the meaning of while(some random integer number)? I thought that the argument must be a statement that is either true or false.
=> Yes you are right while condition checks for true and false. In case of integer, 0 is treated as false and rest of the integers as true. So, whenever number become 0, while loop will break.
Q.2 Could someone explain to me what seen[digit]++ does. And when its true or false?
=> seen is declared as an array of size 10 and initialized all entries as 0. So initially every entry of array seen is zero i.e. seen[0] = 0, seen[1] = 0, seen[2] = 1... seen[9] = 0. Now when we find digit and perform seen[digit]++ it will increase value by 1 every time.
Ok so:
Every number not equal to 0 is true and equal to 0 is false. For example 1 2 and 3 are true, but 0 is false. So while (number) will iterate as long as number != 0
seen[digit]++ first returns the value, then increments itself by one after returning the value.
The condition if(number) is same as if(number != 0).
Point 2: After we have processed the last digit in the number, the value of number/10 will be 0 (as the last digit belongs to 0-9) and there we end our loop.
Point 5: The increment number will increment the value in the array and return the old value. If the value is incremented to 2, then it means that the digit is not unique and increment operation returns us 1 and the if condition is satisfied.
In C++ 0 evaluates to false and any other number evaluates to true. That "random number" is actually modified inside the loop with number /= 10. Division of integer numbers in C++ is special in the sense that it does not yield fractions so 51/10 = 5 and 5/10 = 0. At some point number equals 0 and the loop ends.
seen[digit]++ is a commonly used trick. You lookup the table seen at position digit return the current value and increment the value by 1. So if you would modify your example code like this:
#include <iostream>
using namespace std;
int main(){
int seen[10] = {0};
cout << seen[7]++ << endl;
cout << seen[7] << endl;
}
Your console output should be:
0
1
There is also ++seen[digit] which would first increment and then return the value so you would get:
1
1

/= operation in C++

As I understand this code returns the number of digits entered in the function but I don't understand this operation:
(number /= 10) != 0 at all..I understand that this line
number /= 10
equal to number = number / 10 but why not but why in this function they don't write number / 10 != 0? and what are the differences?
std::size_t numDigits(int number) // function definition.
{ // (This function returns
std::size_t digitsSoFar = 1; // the number of digits
// in its parameter.)
while ((number /= 10) != 0) ++digitsSoFar;
return digitsSoFar;
}
(number /= 10) != 0
This actually has 3 steps. It...
Calculates number / 10
Assigns that value to number
Checks if that value is not equal to 0
So in answer to your question, "why in this function they don't write number / 10 != 0," let's walk through what that does:
Calculates number / 10
Checks if that value is not equal to 0
Can you see the difference between the two?
If you're still not sure why this matters, put an output statement in the while loop that'll show number and digitsSoFar and try to run that function both the way it's written and then with your proposed version.

Cross sum calculation, Can anyone explain the code please?

i'm going to learn C++ at the very beginning and struggling with some challenges from university.
The task was to calculate the cross sum and to use modulo and divided operators only.
I have the solution below, but do not understand the mechanism..
Maybe anyone could provide some advice, or help to understand, whats going on.
I tried to figure out how the modulo operator works, and go through the code step by step, but still dont understand why theres need of the while statement.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0)
{
crossSum = crossSum + input % 10;
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
Lets say my input number is 27. cross sum is 9
frist step: crossSum = crossSum + (input'27' % 10 ) // 0 + (modulo10 of 27 = 7) = 7
next step: input = input '27' / 10 // (27 / 10) = 2.7; Integer=2 ?
how to bring them together, and what does the while loop do? Thanks for help.
Just in case you're not sure:
The modulo operator, or %, divides the number to its left by the number to its right (its operands), and gives the remainder. As an example, 49 % 5 = 4.
Anyway,
The while loop takes a conditional statement, and will do the code in the following brackets over and over until that statement becomes false. In your code, while the input is not equal to zero, do some stuff.
To bring all of this together, every loop, you modulo your input by 10 - this will always return the last digit of a given Base-10 number. You add this onto a running sum (crossSum), and then divide the number by 10, basically moving the digits over by one space. The while loop makes sure that you do this until the number is done - for example, if the input is 104323959134, it has to loop 12 times until it's got all of the digits.
It seems that you are adding the digits present in the input number. Let's go through it with the help of an example, let input = 154.
Iteration1
crossSum= 0 + 154%10 = 4
Input = 154/10= 15
Iteration2
crossSum = 4 + 15%10 = 9
Input = 15/10 = 1
Iteration3
crossSum = 9 + 1%10 = 10
Input = 1/10 = 0
Now the while loop will not be executed since input = 0. Keep a habit of dry running through your code.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0) // while your input is not 0
{
// means that when you have 123 and want to have the crosssum
// you first add 3 then 2 then 1
// mod 10 just gives you the most right digit
// example: 123 % 10 => 3
// 541 % 10 => 1 etc.
// crosssum means: crosssum(123) = 1 + 2 + 3
// so you need a mechanism to extract each digit
crossSum = crossSum + input % 10; // you add the LAST digit to your crosssum
// to make the number smaller (or move all digits one to the right)
// you divide it by 10 at some point the number will be 0 and the iteration
// will stop then.
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
but still dont understand why theres need of the while statement
Actually, there isn't need (in literal sense) for, number of digits being representable is limited.
Lets consider signed char instead of int: maximum number gets 127 then (8-bit char provided). So you could do:
crossSum = number % 10 + number / 10 % 10 + number / 100;
Same for int, but as that number is larger, you'd need 10 summands (32-bit int provided)... And: You'd always calculate the 10 summands, even for number 1, where actually all nine upper summands are equal to 0 anyway.
The while loop simplifies the matter: As long as there are yet digits left, the number is unequal to 0, so you continue, and as soon as no digits are left (number == 0), you stop iteration:
123 -> 12 -> 1 -> 0 // iteration stops, even if data type is able
^ ^ ^ // to store more digits
Marked digits form the summands for the cross sum.
Be aware that integer division always drops the decimal places, wheras modulo operation delivers the remainder, just as in your very first math lessons in school:
7 / 3 = 2, remainder 1
So % 10 will give you exactly the last (base 10) digit (the least significant one), and / 10 will drop this digit afterwards, to go on with next digit in next iteration.
You even could calculate the cross sum according to different bases (e. g. 16; base 2 would give you the number of 1-bits in binary representation).
Loop is used when we want to repeat some statements until a condition is true.
In your program, the following statements are repeated till the input becomes 0.
Retrieve the last digit of the input. (int digit = input % 10;)
Add the above retrieved digit to crosssum. (crosssum = crosssum + digit;)
Remove the last digit from the input. (input = input / 10;)
The above statements are repeated till the input becomes zero by repeatedly dividing it by 10. And all the digits in input are added to crosssum.
Hence, the variable crosssum is the sum of the digits of the variable input.

How does this program print number's digits in reverse?

#include <iostream>
int main() {
int nr;
std::cin>>nr;
while (nr > 0) {
int digit = nr % 10;
nr /= 10;
std::cout<<digit;
}
return 0;
}
Can someone please explain the workflow of this program, basically with the input "32" it outputs "23", that is good, thats my goal, my question is, why does it say "23" instead of just "2", why is the "3" being added in the end if i only said "cout digit". I get that the "3" comes from " nr /= 10", but why is it being outputed near the "2" to farm the answer "23"?
I get that the "3" comes from nr /= 10
Before the program gets to printing 3, it prints 2, which is a remainder you get after dividing 32 by 10.
The result of this division is, indeed, 3. Next loop iteration picks it up, and prints it, because 3 % 10 is 3.
The while makes two iterations. It tests if the condition is true, executes what is inside. Digit takes the value 2, nr becomes 3, it outputs 2. Then for the second iteration, nr is still bigger than 0, so digit becomes 3, nr becomes 0, it outputs 3. The condition is no longer met, so it exits the loop. (Using 23 as an input, that is)
Flow of your code
Your code works a follows (assuming you have entered the number 32, thus the variable nr is 32).
First iteration
Step 1
while(32 > 0)
result: true.
Step 2
int digit = nr % 10;
result: digit now contains the value 2 due to the remainder (%) operation.
Step 3
nr /= 10;
result: nr now contains the value 3, because 32 / 10 results in 3.2 which is a float, but since you are assigning this
number to an integer it implicit converts to the number 3.
Step 4
std::cout<<digit;
result: 2 (the variable digit is still unaffected since the remainder operation 2).
Second iteration
Step 1
while(3 > 0)
result: true (the condition in the while-loop get called again and the variable nr is 3).
Step 2
int digit = nr % 10;
result: digit now contains the value 3, because 3 % 10 = 3.
Step 3
nr /= 10;
Is not relevant anymore for any changes of the flow besides that the while-loop will terminate.
Step 4
std::cout<<digit;
result: 3 (since the digit variable is now 3).
So the complete output will be 23.
Because the while loop means the code within it is repeated until the condition is no longer satisfied. For a two digit number the print statement will therefore be executed twice.

C++ reading a sequence of integers

gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.