1. 程式人生 > 其它 >位運算與常用函式庫

位運算與常用函式庫

位運算

& 與

| 或

~ 非

^ 異或

>> 右移

<< 左移

常用操作:

(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的最大整數(假設一定存在):

int y = *--upper_bound(a.begin(), a.end(), x);