C++标准库使用


C++标准库使用

========================

测试了一些标准库提供的数据结构和函数等

值得一提的是那个自动推导auto用着非常舒服,可自动推导容器内的变量类型、函数的返回值类型等。
模板就不用说了,一行胜百行。需要大量重复的工作,还是建议用模板,模板的效率我还没时间去测试,不过不管怎么样,模板真方便。

template <typename T>
auto printData(const T& v){
    for (auto i: v) {
        cout<<i<<" ";
    }
}

以下是.hpp文件和.cpp文件

//
//  test.hpp
//  Code
//
//  Created by 张赛东 on 2022/1/6.
//

#ifndef test_hpp
#define test_hpp

#include "stdc++.hpp"

using namespace std;
using gg = long long;

class Test {
    int testThings;
public:
    int func();
    int func2();
};
#endif /* test_hpp */
//
//  test.cpp
//  Code
//
//  Created by 张赛东 on 2022/1/6.
//

#include "test.hpp"

bool cmp(gg a, gg b) { return a<b; }

struct Compare {
//    gg score;
//    Compare(gg s):score(s){}
    bool operator() (const gg& s1, const gg& s2)const {
        return s1 < s2;
    }
};

template <typename T>
auto printData(const T& v){//可能改变的话,就需要用引用&, 引用可被修改,值类型固定
    for (auto i: v) {
        cout<<i<<" ";
    }
}

auto lowerBound1(vector<gg>& v, gg left, gg right, gg x, gg a) {
    while(left<right){
        gg mid = (left+right)/2;
        if(v[mid]>x)
            right=mid;
        else
            left=mid+1;
    }
    return left>right or v[left]>x?left:a;
}

int Test::func(){
    vector<gg>v={2,1,4,3,6,5,8,10,5,3};
    //sort(v.begin(),v.end());
    sort(v.rbegin(),v.rend());
    cout<<"V:\n";
    //cout<<&v<<"\n";
//    for (gg i: v) {
//        cout<<i<<" ";
//    }
    printData(v);
    
    reverse(v.begin()+4, v.begin()+6);//转置了第5(4+1)、6(5+1)个位置,6是开区间所在
    cout<<"\n\n";
    printData(v);
    
    sort(v.begin(), v.end());//必须先排序,才能用unique去重,因为unique只看相邻的元素。
    cout<<"This is v";
    printData(v);
    //auto it = unique(v.begin(), v.end());
    vector<gg>::iterator it = unique(v.begin(), v.end());
    v.erase(it, v.end());
    cout<<"\n\n";
    printData(v);
    
    cout<<"\n\n";
    auto it2 = remove(v.begin(), v.end(), 8);
    v.erase(it2,v.end());
    printData(v);
    
    reverse(v.begin(), v.end());
    partial_sort(v.begin(), v.begin()+4, v.end());
    cout<<"\n\n";
    printData(v);
    
    reverse(v.begin(), v.end());
    v.insert(v.begin(),{20, 29, 88, 15, 65, 3, 8 ,9});
    nth_element(v.begin(), v.begin()+6, v.end());//将第6小的数字放到v[6]的位置(即第七个位置)上去,且其前面的数字必小于它,其后面的数字必大于它。
    cout<<"\n\nThis is v:";
    printData(v);
    
    cout<<"\n\nThis is v:";
    //任何二分查找算法都必须排序,没有顺序,还何谈二分。
    sort(v.begin(), v.end()-1);
    printData(v);
    cout<< "\n";
    //用v.end()-1比较好,因为v.end()它背后其实也还是有数字的,如:140704480081848,如果你查的数大于所有元素,那么此时会显示v.end()背后的值。
    //当要读取值时,考虑v.end()-1,其他时候没必要。
    cout<<*v.begin()<<" "<<*(v.end()-1)<<" "<<*v.end()<<" "<<*v.rbegin()<<"\n";
    //输出第一个大于等于该数的值
    cout<< *lower_bound(v.begin(), v.end()-1, 140704480081848)<< " " << *lower_bound(v.begin(), v.end()-1, 65)
    //输出第一个大于该数的值
    <<"\n"<< *upper_bound(v.begin(), v.end()-1, 9)<< " " << *upper_bound(v.begin(), v.end()-1, 65, cmp);
    
    //输出第一个大于等于该数的值所在位置索引。
    cout<<"\n\n";
    cout<<"Position:"<<lowerBound1(v, 0, v.size()-1, 9, -1)<<" "<<lowerBound1(v, 0, v.size()-1, 65, -1);
    
    //将序列调整为大根堆,即大顶堆。
    make_heap(v.begin(), v.end());
    cout<<"\n\n";
    printData(v);
    
    //将大根堆序列调整为升序,即堆排序。
    sort_heap(v.begin(), v.end());
    cout<<"\n\n";
    printData(v);
    

    sort(v.begin(), v.end(), greater<gg>());
    //如序列已是最大的排列,将序列重排为最小的排列
    next_permutation(v.begin(), v.end());
    cout<<"\n\n";
    printData(v);
    
    sort(v.begin(), v.end(), greater<gg>());
    cout<<"\n\n"<<*v.data();
    cout<<"\n\nMax:"<<*max_element(v.begin(), v.end());
    cout<<"\n\nMin:"<<*min_element(v.begin(), v.end());
    //取值型的最好用v.end()-1。
    cout<<"\n\nthe Max:"<<*minmax(v.begin(), v.end()-1).first<<"\n\nthe Min:"<<*minmax(v.begin(), v.end()-1).second;
    
    cout<<"\n\nthe sum:";
    //0表示初始值
    cout<<accumulate(v.begin(), v.end(), 0)<<" "<<accumulate(v.begin(), v.end(), 100);
    
    
    gg v2[100] = {6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 58, 4, 6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 51, 4,6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 57, 4, 6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 56, 4};
    //sort(v2,v2+5);
    //sort(v2, v2+3);
    sort(v2, v2+10, greater<gg>());//10是开区间所在,故排序了第1(0+1)、……10(9+1)个位置。
    sort(v2+10, v2+20, less<gg>());
    sort(v2+20, v2+30, cmp);
    sort(v2+30, v2+40, Compare());
    sort(v2+40, v2+50, [](gg& a,gg& b){return a>b;});
    partition(v2,v2+100, [](gg a){ return a!=3 && a!=7; });//符合条件的放到序列前方,不符合的放到序列后方
    
    cout<<"\nV2:\n";
    int times = 0;
    for(gg i:v2) {
        ++times;
        cout<<i<<" ";
        if(times%10 == 0)
            cout<<"\n";
    }
    cout<<"\n\n";
    printData(v2);
 
    cout<<"\nV3:\n";
    char v3[20] = {'e','c','b','a','d','g','f','h','j','f','f'};//后面的默认为' ',即空字符。
    sort(v3, v3+20);
    cout<<"\n\n";
    printData(v3);
    //如序列已经是最小序列,则重排为最大序列
    prev_permutation(v3, v3+20);
    cout<<"\n\n";
    printData(v3);
    
    //将'u'赋值给指定位置元素,递增后的值赋值给下一个元素
    iota(v3+10, v3+20, 'u');
    cout<<"\n\n";
    printData(v3);
    
    int v4[] = {3,2,1};
    int v5[] = {2,1,3};
    //向量内积
    cout<<"\n\n"<<inner_product(v4, v4+3, v5, 0);
    
    int v6[] = {0,1,2,3,4,5,6,7,8,9};
    //这里多输出个地址不知道怎么回事
    cout<<"\n\n"<<partial_sum(v6, v6+10, v6);
    printData(v6);
    
    vector<int> v7 = {0,1,2,3,4,5,6,7,8,9};
    cout<<"\n\n";
    //前缀和,即前n项和。
    partial_sum(v7.begin(), v7.end(), v7.begin());
    printData(v7);
    
    //前缀和的逆向操作。
    cout<<"\n\n";
    adjacent_difference(v7.begin(), v7.end(), v7.begin());
    printData(v7);
    
    cout<<"\n\n";
    bitset<8> b(257);
    cout<<b<<" "<<b.flip()<<" "<<b.to_ulong()<<" "<<b.to_ullong()<<"\n";
    
    bitset<16> b2(257);//整数的二进制表示
    cout<<b2<<" "<<b2.flip()<<" "<<b2.to_ulong()<<" "<<b2.to_ullong()<<"\n"
    <<(b2<<2)<<" "<<(b2>>1)<<"\n"<<(b2<<=2)<<" "<<(b2>>=1)<<"\n"
    <<b2<<" "<<~b2<<" "<< (b2&=255) <<'\n'
    <<(b2^=255)<<" "<<(b2|=255)<<" "<<(b2^=255) <<'\n'
    <<b2[12]<<" "<<b2.count()<<" "<<~b2<<" "<<(b2|=255)<<" "<<b2.count()<<'\n'//count: b2中true即1的位数
    <<b2.reset()<<" "<<b2.all()<<" "<<b2.any()<<" "<<b2.none()<<'\n';
    
    cout<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")<<'\n';
    cout<<showpos<<20<<" "<<100<<" "<<20-50<<'\n';//展示正负号
    cout<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")<<'\n';
    cout<<noshowpos<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")
    <<" "<<stol("23453")<<" "<<stoll("1043791749713284")<<'\n';
    
    string str = "00001234";
    str.erase(0, str.find_first_not_of('0'));//第一个不是0的数字。
    cout<<str<<'\n';
    cout<<'8' - '0'<<'\n';
    
    string str2 = "63433";
    for (char c: str2) {
        c-= '2';
    }
    cout<<str2<<'\n';
    
    cout<<fixed<<setprecision(10)<<1e5<<" "<<200e5<<" "<<(double)3e-8<<'\n';//1乘以10的5次方
    
    //并查集
    vector<gg> ufs(1e2);
    iota(ufs.begin(), ufs.end(), 0);//赋值函数
    printData(ufs);
    cout<<"\n";
    
    return 0;
}

int Test::func2(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    string s;
    getline(cin, s);
    cout<<s;
    return 0;
}


文章作者: 张赛东
文章链接: https://zsd.name
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张赛东 !
评论
  目录