位運算與常用函式庫
& 與
| 或
~ 非
^ 異或
>> 右移
<< 左移
常用操作:
(1) 求x的第k位數字 x >> k & 1
(2) lowbit(x) = x & -x,返回x的最後一位1
常用庫函式
(1) reverse 翻轉
翻轉一個vector:
reverse(a.begin(), a.end());
翻轉一個數組,元素存放在下標1~n:
reverse(a + 1, a + 1 + n);
【參考程式碼】
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
//翻轉一個vector
vector<int> a({1,2,3,4,5});
reverse(a.begin(),a.end());
for(int x:a) cout<< x<< " ";
cout<<endl;
//翻轉一個數組
int b[5]={1,2,3,4,5};
reverse(b, b + 5);
for(int x:b) cout<< x<< " ";
return 0;
}
輸出結果:
5 4 3 2 1 5 4 3 2 1
(2) unique 去重
返回去重之後的尾迭代器(或指標),仍然為前閉後開,即這個迭代器是去重之後末尾元素的下一個位置。該函式常用於離散化,利用迭代器(或指標)的減法,可計算出去重後的元素個數。
把一個vector去重:
int m = unique(a.begin(), a.end()) – a.begin();
把一個數組去重,元素存放在下標1~n:
int m = unique(a + 1, a + 1 + n) – (a + 1);
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int a[7] = {1,3,2,4,3,1,2};
//先將陣列進行排序,使得相同的元素挨在一起
sort(a,a + 7);
// 返回去重後陣列的個數
int m = unique(a,a + 7) - a;
for(int i = 0; i < m; i++)
cout<< a[i]<< " ";
cout<<endl;
vector<int>b({1,3,2,4,3,1,2});
sort(b.begin(), b.end());
int k = unique(b.begin(), b.end()) - b.begin();
for(int i = 0; i < k; i++)
cout<< a[i]<< " ";
return 0;
}
輸出結果:
1 2 3 4 1 2 3 4
(3) random_shuffle 隨機打亂
作用:幫我們生成隨機資料
#include<iostream>
#include<algorithm>
#include<vector>
#include<ctime>
using namespace std;
int main()
{
srand(time(0));// 重新整理當前時間
vector<int>b({1,2,3,4,5});
random_shuffle(b.begin(), b.end());
for(int x : b)
cout<<x<< " ";
return 0;
}
用法與reverse相同
(4) sort
對兩個迭代器(或指標)指定的部分進行快速排序。可以在第三個引數傳入定義大小比較的函式,或者過載“小於號”運算子。
#include<iostream>
#include<algorithm>
#include<vector>
#include<ctime>
using namespace std;
int main()
{
srand(time(0));// 重新整理當前時間
vector<int>b({1,2,3,4,5});
random_shuffle(b.begin(), b.end());
for(int x : b)
cout<<x<< " ";
cout<<endl;
sort(b.begin(), b.end()); //預設: 從小到大
for(int x : b)
cout<<x<< " ";
cout<<endl;
sort(b.begin(), b.end(), greater<int>()); // 從大到小:加一個引數greater<int>()
for(int x : b)
cout<<x<< " ";
return 0;
}
自定義:
bool cmp(int a, int b) // a 是否應該排在b 的前面
{
return a > b;
}
sort(a , a + n, cmp);
把自定義的結構體vector排序,過載“小於號”運算子:
struct rec{ int id, x, y; }
vector<rec> a;
bool operator <(const rec &a, const rec &b) {
return a.x < b.x || a.x == b.x && a.y < b.y;
}
sort(a.begin(), a.end());
(5) lower_bound/upper_bound 二分
lower_bound 的第三個引數傳入一個元素x,在兩個迭代器(指標)指定的部分上執行二分查詢,返回指向第一個大於等於x的元素的位置的迭代器(指標)。
upper_bound 的用法和lower_bound大致相同,唯一的區別是查詢第一個大於x的元素。當然,兩個迭代器(指標)指定的部分應該是提前排好序的。
在有序int陣列(元素存放在下標1~n)中查詢大於等於x的最小整數的下標:
int I = lower_bound(a + 1, a + 1 + n,. x) – a;
在有序vector<int> 中查詢小於等於x的最大整數(假設一定存在):