位运算与常用函数库

位运算

& 与

| 或

~ 非

^ 异或

>> 右移

<< 左移

 

常用操作:

(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);

 

posted @ 2021-10-14 20:39  时间最考验人  阅读(57)  评论(0编辑  收藏  举报