content
2. Several interesting bit operations
One problem and three solutions: the number of 1 in binary
Determine if a number is an exponent of 2
5. Improve bit operation thinking
Swap the parity bits of an integer
Binary representation of floating point real numbers
Occurs K times and Occurs once
1. Bit operations and bases
Strange tricks for bit operations:
- Judging parity
- Get binary bit is 1 or 0
- Swap the values of two integer variables
- Find the absolute value of an integer without using a judgment statement
- >> and << operators shift bits to the right or left
- >>> operator will fill high bits with 0; >> operator fills high bits with sign bit, no <<< operator
- For int, 1<<35 is the same as 1<<3
- AND: both are 1, the result is 1; or: one is 1, the result is 1; XOR: the two are not the same, the result is 1
a b ~a a&b a|b a^b 1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0 0 0
2. Several interesting bit operations
|
1. Convert English characters to lowercase using or operation and space
('a' | ' ') = 'a'
('A' | ' ') = 'a'
2. Use AND operation &
and underscore to convert English characters to uppercase
('b' & '_') = 'B'
('B' & '_') = 'B'
3. Use XOR operation ^
and spaces to exchange upper and lower case of English characters
('d' ^ ' ') = 'D'
('D' ^ ' ') = 'd'
4. Determine whether two numbers are of the same sign
int x = -1, y = 2;
boolean f = ((x ^ y) < 0); // true
int x = 3, y = 2;
boolean f = ((x ^ y) < 0); // false
5. Swap two numbers without temporary variables
int a = 1, b = 2;
a ^= b;
b ^= a;
a ^= b;
// a = 2, b = 1
6. Add one
int n = 1;
n = -~n;
// n = 2
7. minus one
int n = 2;
n = ~-n;
// n = 1
ps: The above operation can be used for cups in front of friends, but it has no practical use.
3. Use n&(n-1)
n &(n-1)
This operation is common in algorithms and acts to eliminate n
the last 1 in the binary representation of a number .
The core logic is that it n - 1
must be possible to eliminate the last 1, and at the same time change the subsequent 0s into 1s, so that the sum operation is n
performed again &
, and only the last 1 can be turned into 0.
Here's an example of how to use it:
One problem and three solutions: the number of 1 in binary
Method 1: The integer n is bitwise and 1, that is, n&1, (bitwise and: the result is 1 to be 1), when n is expressed in binary as the rightmost 1, then n&1 is 1, count++ once, and then n Move to the right >> compare one by one.
Go directly to the code:
#include<stdio.h>
int main()
{
int n;
int ants = 0;
scanf("%d",&n);
for (int i = 0; i < 32; i++)
{
int m = n;
if ((m>>i)&1== 1)
ants++;
}
printf("%d", ants);
return 0;
}
Method 2: Similar to the method, that is, keep the integer n unchanged and move 1 to the left; the code is not provided here, and you are interested in trying it.
Method 3: Use the n&n(-1) explained above, which will not be explained in detail here, you can see the above
int hammingWeight(int n) {
int res = 0;
while (n != 0) {
n = n & (n - 1);
res++;
}
return res;
}
Determine if a number is an exponent of 2
If a number is an exponent of 2, its binary representation must contain only one 1 :
2^0 = 1 = 0b0001
2^1 = 2 = 0b0010
2^2 = 4 = 0b0100
If n & (n-1)
the technique used is very simple (note the operator precedence, the parentheses cannot be omitted):
boolean isPowerOfTwo(int n) {
if (n <= 0) return false;
return (n & (n - 1)) == 0;
}
A small test
>>>The index of 2 (the title code has been shown above, if you have any questions, you can discuss it in the comment area)
4. For use a ^ a = 0
The nature of the XOR operation is something we need to keep in mind:
The result of XOR operation between a number and itself is 0, ie a ^ a = 0
; the result of XOR operation between a number and 0 is itself, ie a ^ 0 = a
.
Find the number of orders
For this question, as long as we XOR all the numbers, the paired numbers will become 0. The XOR of the single number and 0 is still itself, so the final XOR result is the element that only appears once. :
int singleNumber(int[] nums) {
int res = 0;
for (int n : nums) {
res ^= n;
}
return res;
}
A small test
>>> a number that only appears once
5. Improve bit operation thinking
Swap the parity bits of an integer
The parity swap of integers here is actually the swap of parity bits on binary. Instead of the parity swap on decimal, 15, replace it with 51. For example, replace 1010 with 0101;
Idea: input an integer, make it bitwise and 010101... keep the value of the even number as ou (this sentence needs taste), and then make it bitwise and 101010... keep the odd value as ji , then move ou to the left << one bit, ji to the right >> one bit, and then XOR it to achieve the desired purpose.
Code:
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int ji = n & 0xaaaaaaaa;//1010...
int ou = n & 0x55555555;//0101...
int c= (ou << 1) ^(ji >> 1);
printf("%d",c);
return 0;
}
binary representation of floating point real numbers
Code:
0.625 0.5+0.125
0.101
#include<iostream>
using namespace std;
int main()
{
double n;
cin >> n;
string s1 = "0.";
while (n > 0)
{
n= n * 2;
if (n >=1)
{
s1 +="1";
n = n - 1;
}
else {
s1 += "0";
n = n;
}
if (s1.size() > 34)
{
cout << "ERROR " << endl;
}
}
cout << s1 << endl;
return 0;
}
Occurs K times and Occurs once
The breakthrough of solving the problem: the conclusion that the result is 0 by using k K-ary numbers to add without carry
First convert the decimal number to k-ary, and use the string to store in reverse order.
Use the remainder method of dividing by k (a general calculation method) to convert the number in the array to k-ary number.Because it needs to be calculated by bit (column) after conversion to k-ary, it is stored in the form of a string. After conversion to k-ary system, due to the different sizes of the numbers, the lengths may also be different. Although the sum is 0 for numbers with k numbers, there is no difference, but the bit sequence is very important for the required number, (calculation When the string is calculated from left to right, and when converted back to decimal, it is calculated from right to left), so the numbers converted to k-base are stored in reverse order .
Find the maximum length of the string, and then fill in the string that is less than maxlen.
Because it needs to be calculated column by column, it is necessary to know how many columns there are at most, that is, maxlen. Fill "0" in the high order, make up the maxlen length, so as to do bit-by-bit addition without carryAdd without carry
Add these numbers without carry, which is equivalent to the XOR operation ^, or take the number after the bitwise addition modulo kOutput result, K-ary to decimal
This step is simple, the same principle as the common octal-to-decimal and hexadecimal-to-decimal.
#include<iostream>
#include<algorithm>
#include<string>
//#include<cmath>
using namespace std;
string decTok(int dec, int k); //十进制数转K进制
int kTodec(string str, int k); // K进制转十进制
string decTok(int dec, int k)
{
string ret = ""; //作为结果
while (dec > 0) {
ret += char(dec%k + '0');//如:5+'0'='5'
dec /= k;
}
reverse(ret.begin(), ret.end());//翻转
return ret;
}
int kTodec(string str, int k)
{
int ans = 0;
for (int i = 0; i < str.size(); i++)
ans = ans * k + (str[i] - '0');//020 首位是最高位
return ans;
}
int main()
{
int n[] = { 1,1,1,3,3,3,5,5,5,9,9,9,6,7,7,7 };
int k = 3; //根据数组数据,要转换的进制
//1.十进制数转K进制
string str[16];
for (int i = 0; i < 16; i++)
str[i] = decTok(n[i], k);
//2.找出16条字符串中最大长度
int maxlen = 0;
int len;
for (int i = 0; i < 16; i++) {
len = str[i].size();
maxlen = max(maxlen, len); //maxlen=max(maxlen,str[i].size())
}
//16条字符串中,若字符串长度<maxlen,则进行补齐,以便逐位做不进位加法
for (int i = 0; i < 16; i++)
while (str[i].size() < maxlen)
str[i] = "0" + str[i];
//ans:结果初始化
string ans = "";
while (ans.size() < maxlen)
ans += "0";
//3.做不进位加法
for (int i = 0; i < 16; i++)
for (int j = 0; j < maxlen; j++)
ans[j] = char(((str[i][j] - '0') + (ans[j] - '0')) % k + '0');
cout << ans << endl; //ans字符串结果
cout<< kTodec(ans, k); //转为十进制数
return 0;
}