STL常用容器和算法

2018-12-21  本文已影响0人  漫游之光

主要是方便查阅,每次都要去网上找感觉比较麻烦,作为笔记写在这里。这里是我在做算法题的时候,需要去查阅的STL中的容器和算法,所以,最常用的这里没有列举。

string

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main(int argc, char const *argv[])
{
    string s;
    // getline(cin,s); //读取一行,以换行作为分隔符
    // cin>>s; //读取一个字符串,以空格、换行作为分隔符
    int num = 12345678;
    s = to_string(num); //数字转字符串

    int p1 = s.find("3",0); //字符串查找
    int p2 = s.find('4',0);
    if(p1 != string::npos && p2 != string::npos){
        s = s.substr(p1,p2 - p1 + 1);
        cout<<s<<endl; //截取字符串
    }
    num = stod(s); //字符串转数字 num = 34

    /* 读取一个表达式中数字 */
    string expression = "7+3*4*5+2+4-3-1";
    istringstream iss(expression);
    ostringstream oss; 
    while(!iss.eof()){
        char c = iss.peek(); //查看第一个字符,但不读出
        // iss.putback(c); //可以将一个字符压回到输入流
        if(c >= '0' && c <= '9'){
            int tmp;
            iss>>tmp;
            oss<<tmp<<" ";
        }else{
            iss>>c;
        }
    }
    cout<<oss.str()<<endl;
    return 0;
}

正则表达式

遇到字符串的问题,特别是匹配的问题,可以先考虑能否用正则表达式处理。个人感觉,正则表达式算是一个处理字符串神器。

使用正则表达式需要使用头文件regex,其中,有以下常用组件。

#include <iostream>
#include <string>
#include <regex>
using namespace std;


int main(int argc, char const *argv[])
{
    /* 检查一个字符串是否为一个有效的ip地址 regex构造时可能会抛出异常*/
    regex ip("^((25[0-5]|2[0-4]\\d|[1]{1}\\d{1}\\d{1}|[1-9]{1}\\d{1}|\\d{1})($|(?!\\.$)\\.)){4}$");
    vector<string> v = {"127.0.0.1","127.0.1","256.0.0.0"};
    for(int i=0;i<v.size();i++){
        if(regex_match(v[i],ip)){
            cout<<v[i]<<" ";
        }
    }
    cout<<endl;

    /* 找出字符串中所有的数字 */
    string s = "abc123i2cd34jihle233";
    regex num("[0-9]+");
    sregex_iterator it(s.begin(),s.end(),num),end;
    for(;it != end;++it){
        cout<<it->str()<<" ";
    }
    cout<<endl;

     /* 找出字符串中的第一个数字 */
    smatch results;
    if(regex_search(s,results,num)){
        cout<<results.str()<<endl;
    }

    /* 去掉字符串中的数字 */
    string s1 = regex_replace(s,num,""); //这个函数还有更高级的用法
    cout<<s1<<endl;
    return 0;
}

vector

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v;
    for(int i=0;i<10;i++){
        v.push_back(i);
        /* size:存储的数据的大小 capacity:分配空间的大小 */
        cout<<v.size()<<" "<<v.capacity()<<endl;
    }

    /* 可以利用vector的push_back和pop_back方法当做栈使用 */
    /* 在迭代中删除元素 */
    vector<int>::iterator it = v.begin();
    while(it != v.end()){
        if(*it % 2 == 1){
            it = v.erase(it);
        }else{
            ++it;
        }
    }

    for(int i=0;i<v.size();i++){
        cout<<v[i]<<" ";
    }
    cout<<endl;
    return 0;
}

queue、dequeue和priority_queue

#include <iostream>
#include <queue>
using namespace std;

struct cmp{
    bool operator()(int a,int b){
        return a < b;
    }
};

int main(int argc, char const *argv[])
{
    deque<int> deq;
    deq.push_front(2);
    deq.push_back(1);
    deq.pop_back();
    deq.pop_front();
    deq.front();
    deq.back();
    priority_queue<int,vector<int>,cmp> pq;
    pq.push(1);
    pq.pop();
    pq.top();
    return 0;
}

set和map

set和map在刷题的过程中,主要实现动态地查找和更新。个人感觉需要掌握的就是插入、删除,查找和更新。

#include <iostream>
#include <set>
#include <map>
using namespace std;

int main(int argc, char const *argv[])
{
    map<string,int> word;
    for(int i=0;i<10;i++){
        string s;
        char c = 'A' + i;
        s += c;
        word[s] = 1; //如果有,就赋值,没有,就插入新的记录
    }
    if(word.find("A") == word.end()){
        word.insert(make_pair("A",1)); // insert插入时,如果关键字在记录中,什么也不做
    }else{
        word["A"] ++;
    }
    word.erase("B");
    for(map<string,int>::iterator i = word.begin();i != word.end();++i){
        cout<<i->first<<" "<<i->second<<endl;
    }

    set<int> mark;
    for(int i=0;i<10;i++){
        mark.insert(i);
    }
    for(set<int>::iterator i = mark.begin();i != mark.end(); ){
        if(*i % 2 == 1){
            i = mark.erase(i);
        }else{
            i++;
        }
    }
    for(set<int>::iterator i = mark.begin();i != mark.end(); ++i){
        cout<<*i<<" ";
    }
    cout<<endl;
    return 0;
}

常用算法

lambd表达式

C++11支持lambd表达式,个人感觉写算法的时候,还是这个最好用。因为以前使用的是Java,对于不能创建一个匿名对象作为参数还是不习惯。现在C++也支持这种格式。

[capture list](parameter list)->return type {function body}

capture list表示要捕捉的局部变量。

排序和二分查找

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v = {2,6,1,5,9,0,3,8,7,4};
    vector<int> v1 = {5,9};

    vector<int>::iterator i = find(v.begin(),v.end(),3); // 查找元素
    cout<< i - v.begin() <<endl;
    i = search(v.begin(),v.end(),v1.begin(),v1.end()); //查找子序列
    cout<< i - v.begin() <<endl;
    
    sort(v.begin(),v.end()); //还有一个稳定的排序stable_sort
    // lower_bound 返回第一个大于等于val的元素,不存在则返回end
    // upper_bound 返回第一个大于等于val的元素,不存在则返回end
    i = upper_bound(v.begin(),v.end(),30);
    cout<<v.end() - i<<endl;

    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读