Compare two binary numbers and get the different bits [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
I want to write a program to get the number of 1's bit in comparing two numbers.if I compare the bits between any two numbers
to find where the binary numbers are different in the 1's and 0's.
in other words Exclusive OR (XOR) relationship.
like if 22 (which has 10110 binary)and compare it with 15 (which has 01111 binary)
the first one 10110
the second one 01111
the result 11001
and the answer would be 25 but what I want to get is 3 where there is three 1's and 0's that are different.

Hrmmm, the first non-recursive idea that comes to mind is:
int a = ...;
int b = ...;
int x = a ^ b;
int count;
for (int i = 0; i < 32; ++i) {
if (x & (1 << i)) {
++count;
}
}

std::bitset::count should do what you're looking for:
http://www.cplusplus.com/reference/stl/bitset/count/
http://en.cppreference.com/w/cpp/utility/bitset/count

This would be the easiest approach:
int count_bits(int a)
{
int mask;
int count = 0;
for (mask = 1; mask; mask <<= 1)
{
if (mask & a) ++count;
}
return count;
}
If you want something more fancy take a look here: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive

Related

Can someone please explain this bit manipulation code to me?

I am new to competitive programming. I recently gave the Div 3 contest codeforces. Eventhough I solved the problem C, I really found this code from one of the top programmers really interesting. I have been trying to really understand his code, but it seems like I am too much of a beginner to understand it without someone else explaining it to me.
Here is the code.
void main(){
int S;
cin >> S;
int ans = 1e9;
for (int mask = 0; mask < 1 << 9; mask++) {
int sum = 0;
string num;
for (int i = 0; i < 9; i++)
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
if (sum != S)
continue;
ans = min(ans, stoi(num));
}
cout << ans << '\n';
}
The problem is to find the minimum number whose sum of digits is equal to given number S, such that every digit in the result is unique.
Eq. S = 20,
Ans = 389 (3+8+9 = 20)
Mask is 9-bits long, each bit represents a digit from 1-9. Thus it counts from 0 and stops at 512. Each value in that number corresponds to possible solution. Find every solution that sums to the proper value, and remember the smallest one of them.
For example, if mask is 235, in binary it is
011101011 // bit representation of 235
987654321 // corresponding digit
==> 124678 // number for this example: "digits" with a 1-bit above
// and with lowest digits to the left
There are a few observations:
you want the smallest digits in the most significant places in the result, so a 1 will always come before any larger digit.
there is no need for a zero in the answer; it doesn't affect the sum and only makes the result larger
This loop converts the bits into the corresponding digit, and applies that digit to the sum and to the "num" which is what it'll print for output.
for (int i = 0; i < 9; i++)
if (mask >> i & 1) { // check bit i in the mask
sum += i + 1; // numeric sum
num += char('0' + (i + 1)); // output as a string
}
(mask >> i) ensures the ith bit is now shifted to the first place, and then & 1 removes every bit except the first one. The result is either 0 or 1, and it's the value of the ith bit.
The num could have been accumulated in an int instead of a string (initialized to 0, then for each digit: multiply by 10, then add the digit), which is more efficient, but they didn't.
The way to understand what a snippet of code is doing is to A) understand what it does at a macro-level, which you have done and B) go through each line and understand what it does, then C) work your way backward and forward from what you know, gaining progress a bit at a time. Let me show you what I mean using your example.
Let's start by seeing, broadly (top-down) what the code is doing:
void main(){
// Set up some initial state
int S;
cin >> S;
int ans = 1e9;
// Create a mask, that's neat, we'll look at this later.
for (int mask = 0; mask < 1 << 9; mask++) {
// Loop state
int sum = 0;
string num;
// This loop seems to come up with candidate sums, somehow.
for (int i = 0; i < 9; i++)
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
// Stop if the sum we've found isn't the target
if (sum != S)
continue;
// Keep track of the smallest value we've seen so far
ans = min(ans, stoi(num));
}
// Print out the smallest value
cout << ans << '\n';
}
So, going from what we knew about the function at a macro level, we've found that there are really only two spots that are obscure, the two loops. (If anything outside of those are confusing to you, please clarify.)
So now let's try going bottom-up, line-by-line those loops.
// The number 9 appears often, it's probably meant to represent the digits 1-9
// The syntax 1 << 9 means 1 bitshifted 9 times.
// Each bitshift is a multiplication by 2.
// So this is equal to 1 * (2^9) or 512.
// Mask will be 9 bits long, and each combination of bits will be covered.
for (int mask = 0; mask < 1 << 9; mask++) {
// Here's that number 9 again.
// This time, we're looping from 0 to 8.
for (int i = 0; i < 9; i++) {
// The syntax mask >> i shifts mask down by i bits.
// This is like dividing mask by 2^i.
// The syntax & 1 means get just the lowest bit.
// Together, this returns true if mask's ith bit is 1, false if it's 0.
if (mask >> i & 1) {
// sum is the value of summing the digits together
// So the mask seems to be telling us which digits to use.
sum += i + 1;
// num is the string representation of the number whose sum we're finding.
// '0'+(i+1) is a way to convert numbers 1-9 into characters '1'-'9'.
num += char('0' + (i + 1));
}
}
}
Now we know what the code is doing, but it's hard to figure out. Now we have to meet in the middle - combine our overall understanding of what the code does with the low-level understanding of the specific lines of code.
We know that this code gives up after 9 digits. Why? Because there are only 9 unique non-zero values (1,2,3,4,5,6,7,8,9). The problem said they have to be unique.
Where's zero? Zero doesn't contribute. A number like 209 will always be smaller than its counterpart without the zero, 92 or 29. So we just don't even look at zero.
We also know that this code doesn't care about order. If digit 2 is in the number, it's always before digit 5. In other words, the code doesn't ever look at the number 52, only 25. Why? Because the smallest anagram number (numbers with the same digits in a different order) will always start with the smallest digit, then the second smallest, etc.
So, putting this all together:
void main(){
// Read in the target sum S
int S;
cin >> S;
// Set ans to be a value that's higher than anything possible
// Because the largest number with unique digits is 987654321.
int ans = 1e9;
// Go through each combination of digits, from 1 to 9.
for (int mask = 0; mask < 1 << 9; mask++) {
int sum = 0;
string num;
for (int i = 0; i < 9; i++)
// If this combination includes the digit i+1,
// Then add it to the sum, and append to the string representation.
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
// If this combination does not yield the right sum, try the next combination.
if (sum != S)
continue;
// If this combination does yield the right sum,
// see if it's smaller than our previous smallest.
ans = min(ans, stoi(num));
}
// Print the smallest combination we found.
cout << ans << '\n';
}
I hope this helps!
The for loop is iterating over all 9-digit binary numbers and turning those binary numbers into a string of decimal digits such that if nth binary digit is on then a n+1 digit is appended to the decimal number.
Generating the numbers this way ensures that the digits are unique and that zero never appears.
But as #Welbog mentions in comments this solution to the problem is way more complicated than it needs to be. The following will be an order of magnitude faster, and I think is clearer:
int smallest_number_with_unique_digits_summing_to_s(int s) {
int tens = 1;
int answer = 0;
for (int n = 9; n > 0 && s > 0; --n) {
if (s >= n) {
answer += n * tens;
tens *= 10;
s -= n;
}
}
return answer;
}
Just a quick way to on how code works.
First you need to know sum of which digits equal to S. Since each digit is unique, you can assign a bit to them in a binary number like this:
Bit number Digit
0 1
1 2
2 3
...
8 9
So you can check all numbers that are less than 1 << 9 (numbers with 9 bits corresponding 1 to 9) and check if sum of bits if equal to your sum based on their value. So for example if we assume S=17:
384 -> 1 1000 0000 -> bit 8 = digit 9 and bit 7 = digit 8 -> sum of digits = 8+9=17
Now that you know sum if correct, you can just create number based on digits you found.

How do I proceed with a question like this? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Good Evening everyone. I am not really sure as to whether it is against the rules to ask questions like these on this platform (If it is, kindly tell me). The question is of a "practice competition". I could complete 5 of 10 test cases but I am not sure what is wrong in this. Please suggest any correction/logic/hint... And Time Complexity must be less than O(n^2) (According to the input given)
The approach I tried is:
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
signed long int t, n;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
int count = 0;
scanf("%d", &n);
if (n <= 10)
count = n;
else {
// count = 9;
string s;
s = to_string(n);
int len = s.length();
int x = n / (pow(10, len - 2));
int h = x / 11;
string y = to_string(x);
if (y.length() <= 2)
x = 0;
count = (9 * (len - 1)) + x + h;
}
printf("%d\n", count);
}
return 0;
}
Please suggest whatever you feel is helpful. Thank you so much.
For the problem, given that the work area you are dealing with is relatively small (the number of beautiful numbers less than 10^9 can be reasonably handled with a table of those values), here is a version of a solution that uses a pre-generated table of all of the beautiful numbers in sorted order.
Once the table is set up, it is just a matter of doing a binary search to determine the number of beautiful numbers there are that occur before the input value. The position of the closest beautiful number in the table is the number of beautiful numbers we need.
The binary search is done by utilizing the <algorithm> function std::upper_bound. This function will return an iterator to the item that is greater than the search item. Then to get the position, std::distance is used (we subtract 1, since std::upper_bound will give us the item that is greater than the searched item).
The generation of the table can be done at compile-time (by hand, just initializing an array), or if you're lazy, generated at runtime with a simple loop. Here is one such solution:
#include <algorithm>
#include <vector>
#include <iostream>
std::vector<int> values;
int generate_value(int digit, int numTimes)
{
int total = 0;
for (int i = 0; i < numTimes; ++i)
total = 10 * total + digit;
return total;
}
// I'm lazy, so let the program generate the table for me
void generate_values()
{
size_t curIdx = 0;
values.push_back(0);
for (int i = 1; i <= 9; ++i)
{
for (int j = 1; j <= 9; ++j)
values.push_back(generate_value(j, i));
}
values.push_back(1111111111);
}
// does a binary search and returns the position of the beautiful number
int beautiful(int num)
{
if (num == 0)
return 1;
// get iterator to closest number equaling the beautiful number
auto iter = std::upper_bound(values.begin(), values.end(), num);
// get distance from beginning of vector
return std::distance(values.begin(), iter) - 1;
}
int main()
{
generate_values();
std::cout << beautiful(18) << "\n";;
std::cout << beautiful(1) << "\n";;
std::cout << beautiful(9) << "\n";;
std::cout << beautiful(100500) << "\n";;
std::cout << beautiful(33) << "\n";;
std::cout << beautiful(1000000000) << "\n";;
}
Output:
10
1
9
45
12
81
The size of the table is in total, 83 entries, thus a binary search of this table will take no more than log(83) checks to find the value, which is at most 7 probes in the table.
This is not a complex problem.
Assuming your input is correct so we don’t have to do any checking we observe:
If number n is single digit the number of beautiful numbers is b = n.
If number n is double digit and the first digit is f, then the number of beautiful numbers b = 9 + x, where x is a number of all beautiful double digit numbers smaller than n,
If number n is triple digit and the first digit is f, then the number of beautiful numbers b = 2 x 9 + x, where x is a number of all beautiful triple digit numbers smaller than n.
And so on and on
Thus we can extrapolate: If number n has d digits, than the number of beautiful numbers
s = (d-1) * 9 + x,
where x is a number of beautiful d-digit numbers smaller than or equal to n.
So your problem was reduced to finding x. And this can be reduced even further. Take for instance number n = 44437. The important number here is first digit f. It is trivial to see that all 5 digit beautiful numbers that begin where single digits are less then f are ok. In our example 11111, 22222, 33333 are ok, while 444444 and larger are not.
So all you need to do is to check if beautiful number fffff is smaller than or equal to n. And this can be done with simple traversal of input string.
So your solution would be:
s = (d-1) * 9 + (f-1) + supersecretsauce,
where:
s - solution
n – your input number of age
d – number of digits, assuming your input is always correct is length(n)
f – first digit of your number n
supersecretsauce – 1 if fff…f is smaller or equal than n, 0 if bigger.
And even the traversal of input string can be optimized, but I leave that to you.
Oh yeah... and the time complexity of this solution O(n) = length(n) = log10(n).
A couple of things about the early set up.
1) From the input example you gave, it appears the t and each n need to be input sequentially, but your code prints the number of beautiful numbers before the next input is received. I would suggest reading in t first, then looping through an array of size t to get all the inputs first.
2) The constraints aren't tested. I would test the t and each value in the array mentioned before that the constraints are met, and either have the user try again if they aren't, or simply abort.

need help for write a function that give me all the states of a number

I have a 192-bit number . and I want two write a function that give me all of the states of this number as follows :
1) all the states with one bit 1
2) all the states with two bits 1
3) all the states with three bits 1
.
.
.
and so on till all of the bits will be 1
also I want to write each of this part in a separate files.
I'v just wrote the states that all of the 1-bits are put together.
for example:(for 16-bits number)
0000000000000011----> then I shift the bits to the left. But I can't find a good way to give me all of states of two bits.
(I use miracle library in C for this big number)
do you have any idea?
thank you :)
You could use 6 for-loops (192/32bit) which loop across all the values of a uint32
inside every-for-loop you can multiply the uint32 by some value to get the right value something like this:
for(uint32_t i = 0; i < 0xFFFFFFFF; i++) {
for(uint32_t j = 0; j < 0xFFFFFFFF; j++) {
bignumber = j + 0xFFFFFFFF*i
print(bignumber)
}
}
or if you want to do it really bitwise you could do some bitmasking inside the for-loops
I do not know your functions. but, if you have num and shiftLeft and equals functions, it can be like this
for (int i=0;i<192;i+=2)
{
num->assing(0b11);
num->shiftLeft(i*2);
if (num->andOperand(victim)->equals(num))
{
//this is the number has two consecutive 11, and only
}
if (num->andOperand(victim)->biggerAndEqual(0b11))
{
//this is the number has at least one , two consecutive 11
}
}
As the problem was stated there are ((2 ^ 192) - 1) numbers to print, because all permutations are covered except 0 which contains no 1 bits. That is clearly impossible so the question must be asking for consecutive bits set. As #n.m. wrote, get it working with 4 bits first. Then extend it to 192 bits. To shift a number, you double it. This solution works without doing any bit shifting or multiplication - by addition only (apart from the bit mask in printbits().
#include<stdio.h>
#define BITS 4
unsigned printmask;
void printbits (unsigned num) {
int i;
for (i=0; i<BITS; i++) {
if (num & printmask)
printf ("1");
else
printf ("0");
num = num + num;
}
printf (" ");
}
int main() {
unsigned num, bits;
int m, n;
printmask = 1; // prepare bit mask for printing
for (n=1; n<BITS; n++)
printmask = printmask + printmask;
num = 1;
for (n=0; n<BITS; n++) {
bits = num;
for (m=n; m<BITS; m++) {
printbits (bits);
bits = bits + bits;
}
printf ("\n");
num = num + num + 1;
}
return 0;
}
Program output
0001 0010 0100 1000
0011 0110 1100
0111 1110
1111

different length permutations [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Algorithm to return all combinations of k elements from n
What I want to do is generate all 1-9 permutations of different length. For example all permutations of length one would simply be
{1}, {2}, {3}, {4} .. and so on.
Permutations of length two would be: {1,2}, {1,3}, {1,4} ..
So far I've been using std::next_permutation(), however it won't do the job in this case.
Is there any way to solve this problem without using recursion? If not and you're providing any code I would really appreciate if you would explain to me, because I'm really struggling with recursion right now, especially with implementing recursive solutions myself. Thanks in advance.
The approach I would use starts from hakmem 175 and that is finding the next higher number with the same number of bits.
So let's say that you code in one int you 10 numbers (from bit 0 to bit 9)
That means that you have to loop from 1 to 10 and prime your start int with the first number that will approximate your pair.
ex: for {1},{2} ... the start int would be 2^0
for {1,2} {1,3} ... the start int would be 2^0+2^1
and so on.
after that you have to make a method that would interpret the number (check if a bit is set then the corresponding number will appear in the sequence).
after that call hakmems method for the next number:
unsigned nexthi(unsigned a) {
unsigned c = (a & -a);
unsigned r = a+c;
return (((r ^ a) >> 2) / c) | r);
}
and continue the loop until no numbers remain.
and go to the next number of bits (1->10)
I suggest looking to hakmem method for you to understand how it works, the implementation is easy if you know a few things about bits.
void permute(std::vector<int>& digits, int length) {
if (length == 0) {
std::cout << "{";
for (int i = 0; i < digits.length; i++) {
std::cout << digits[i] << ",";
}
std::cout << "}" << std::endl;
return;
}
for (int i = 0; i < 9; i++) {
std::vector<int> newDigits(digits);
newDigits.push_back(i);
permute(newDigits, length -1);
}
}
Call this within main as
std::vector<int> digits;
permute(digits, 10); // For 10 digit permutations.
Now if you want to get permutations of length 1,2 ... n, then all you have to do is put the permute function inside a loop.
Note that this is not the most efficient of implementations. But I suppose this should illustrate the recursion clearly.

decimal to 8 bit binary conversion in c++

I am working on decimal to binary conversion. I can convert them, using
char bin_x [10];
itoa (x,bin_x,2);
but the problem is, i want answer in 8 bits. And it gives me as, for example x =5, so output will be 101, but i want 00000101.
Is there any way to append zeros in the start of array? or is it possible to get answer in 8 bits straight away? I am doing this in C++
In C++, the easiest way is probably to use a std::bitset:
#include <iostream>
#include <bitset>
int main() {
int x = 5;
std::bitset<8> bin_x(x);
std::cout << bin_x;
return 0;
}
Result:
00000101
To print out the bits of a single digit, you need to do the following:
//get the digit (in this case, the least significant digit)
short digit = number % 10; //shorts are 8 bits
//print out each bit of the digit
for(int i = 0; i < 8; i++){
if(0x80 & digit) //if the high bit is on, print 1
cout << 1;
else
cout << 0; //otherwise print 0
digit = digit << 1; //shift the bits left by one to get the next highest bit.
}
itoa() is not a standard function so it's not good to use it if you want to write portable code.
You can also use something like that:
std::string printBinary(int num, int bits) {
std::vector<char> digits(bits);
for (int i = 0; i < bits; ++i) {
digits.push_back(num % 2 + '0');
num >>= 1;
}
return std::string(digits.rbegin(), digits.rend());
}
std:: cout << printBinary(x, 8) << std::endl;
However I must agree that using bitset would be better.