一、算術運算符和位運算符
算術運算符:+、-、*、/、%
位運算符:&按位與、|按位或、^按位異或、~按位取反、<<左移右側補0、 >>右移左側補符號位、 >>>右移左側補0
注意:移位運算一定要賦值。也就是說將a左移2位不應該是a<<2;。而應該是a = a<<2;或者a <<= 2;。
二、布隆過濾器
網頁黑名單系統
垃圾郵件過濾系統
爬蟲的網址判斷重複系統
容忍一定程度的失誤率
對空間要求嚴格
三、位運算練習題
1、不使用任何額外存儲空間而交換兩個整數
解法1:
class
Swap
{
public
:
vector<
int
>
getSwap(vector<
int
>
num) {
num[
0
]
= num[
1
]-num[
0
];
num[
1
]
= num[
1
]-num[
0
];
num[
0
]
= num[
0
]+num[
1
];
return
num;
}
};
解法2:
vector<int>
getSwap(vector<int>
num) {
num[0] ^= num[1];
num[1] ^= num[0];
num[0] ^= num[1];
returnnum;
}
};
2、比較兩個數的大小,不使用任何比較語句
解法:不使用比較語句而判斷出大小,首先想到用1、0和a、b兩數的線性組合來判斷大小。然後分析返回a有哪些情況,把這種情況用一個變量來記錄,把返回b的情況用另一個變量來記錄。情況分析如下表(+表示非負):
a
|
b
|
a-b
|
返回值 |
+
|
+
|
+
|
a
|
-
|
-
|
+
|
a
|
+
|
+
|
-
|
b
|
-
|
-
|
-
|
b
|
+
|
-
|
+(溢出-)
|
a
|
-
|
+
|
-(溢出+)
|
b
|
②返回b也有兩種情況:a、b同號且a-b爲負;a、b異號且a爲負。
這樣做可以不直接判斷a-b的符號,因爲有可能溢出。
class
Compare
{
public
:
int
getSign(
int
num)
{
return
((num
>>
31
)&
1
)^
1
;
}
int
getMax(
int
a,
int
b)
{
int
as
= getSign(a);
int
bs
= getSign(b);
int
cs
= getSign(a-b);
int
dif
= as^bs;
int
same
= dif^
1
;
int
reta
= same*cs+dif*as;
int
retb
= reta^
1
;
return
reta*a+retb*b;
}
};
要求:O(N)\O(1)
解法:把所有數進行按位異或運算,出現偶數次的按位異或後爲0,出現奇數次的按位異或後不變。
class
OddAppearance
{
public
:
int
findOdd(vector<
int
>
A,
int
n)
{
int
res
= A[
0
];
for
(
int
i
=
1
;i
< n;i++) {
res
^= A[i];
}
return
res;
}
};
4、一個數組中有兩個數出現了奇數次,其餘數都出現了偶數次,找出這兩個出現奇數次的數
解法:
①遍歷第一遍將所有數據異或,得到出現奇數次的兩個數的異或結果xor;
②xor中爲1的位,在兩個數中一定是不同的,一個數在該位爲1另一個數爲0,找到xor中爲1的位(假設爲第k位);
③再一次遍歷數組,將第k位爲1的數異或,最後得到的結果就是要找的其中一個數,用xor與這個數異或就得到另一個要找的數。
class OddAppearance {
public:
vector<int> findOdds(vector<int> arr, int n) {
int xor
= 0;
vector<int> result;
for (int i = 0;i < n;i++) {
xor ^= arr[i];
}
int temp = xor &(~xor + 1);//
該運算可以找到xor中從右邊起第一個爲1的位,將xor取反可以使第一個1的右邊一位變爲1,加
// 1可以使第一個1的右邊一位進位,從而使第一個1所在的位變爲1,而其他的位均沒有改變,再與
// xor按位與就可以保留下第一個1.
int res1 = 0;
for (int j = 0;j < n;j++) {
if ((arr[j]&temp) != 0) { //先按位與、按位或、按位異或再進行判斷的語句,位運算一定要加括號
res1 ^=arr[j];
}
}
int res2 = xor ^res1;
result.push_back(min(res1,res2));
result.push_back(max(res1,res2));
return result;
}
};