• C++STL泛型编程基础知识讲解--------2015年2月3日


    今天学习了C++STL泛型编程的基础知识,我对主要知识整理如下:

    STL提供三种类型的组件:容器,迭代器,算法。支持泛型程序设计标准。
    容器主要有两类:顺序容器和关联容器。
    顺序容器:vector,list,deque,string等都是一系列连续元素的集合。
    关联容器:set,multiset,map,multimap包含查找元素的键值。
    迭代器:遍历容器
    STL算法库:排序算法,不可变序算法,变序性算法,数值算法。


    /*******************************************************************************************************/
    Vector容器简介
    (1)优势:可以随机访问各个元素还可以在尾部添加元素。因此可以完全代替数组。具有内存自动管理功能,可以随时动态调整内存功能。
    (2)基本内容
    头文件声明:#include<vector>
    vector容器是从下标0开始计数,我们可以事先固定一个大小,事后可以随时调整其大小;也可事先不定义,随时使用push_back()方法从尾部扩张,也可以使用insert()方法在某个元素位置前插入元素。
    vector容器的两个重要方法:
    begin()和end():begin()方法返回首元素位置的迭代器,end()方法返回最后一个元素的下一个元素的位置的迭代器。
    (3)创建对象
    法1:vector<int>v;
    法2:vector<double>v(10);(固定大小)
    法3:vector<double>v(10,8.6);(固定了大小并且初始化)
    (3)元素的尾部扩张
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
    vector<int>v;
    v.push_back(2);
    v.push_back(7);
    v.push_back(9);
    return 0;
    }

    (4)下标访问vector元素
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
    vector<int>v(3);
    v[0]=2;
    v[1]=7;
    v[2]=9;
    cout<<v[0]<<v[1]<<v[2]<<endl;
    return 0;
    }
    (5)使用迭代器访问vector元素
    迭代器的类型必须与遍历的vector对象的元素的类型一致
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
    vector<int>v;
    v.push_back(3);
    v.push_back(6);
    v.push_back(9);
    vector<int>::iterator it;
    for(it=v.begin();it!=v.end();it++)
    {
    cout<<*it<<endl;
    }
    return 0;
    }

    (6)元素的插入
    insert()方法可以在vector对象的任意位置之前插入一个新的元素,同时vector自动扩张一个元素的空间,插入位置后所有元素依次向后挪动一个位置。
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
    vector<int>v(3);
    v[0]=1;
    v[1]=3;
    v[2]=6;
    v.insert(v.begin(),8);
    v.insert(v.begin()+2;9);//在第二个元素前插入元素9
    for(it=v.begin();it!=v.end();it++)
    {
    cout<<*it<<endl;
    }
    return 0;
    }
    (7)元素的删除
    erase()方法可以删除vector中迭代器所指的一个元素或者一段区间的所有元素。clear()方法可以删除所有元素。
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
    vector<int>v(3);
    v[0]=1;
    v[1]=3;
    v[2]=6;
    v.erase(v.begin()+2);//删除第二个元素
    v.erase(v.begin(),v.end());//删除所有元素
    return 0;
    }
    (8)元素的反转
    reverse()方法:头文件是#include<algorithm>
    reverse(v.begin(),v.end());
    (9)元素排序
    sort()方法:头文件#include<algorithm>
    默认方法是升序
    可以自定义排序方法:
    bool cmp(const int &a,const int &b)
    {
    return a>b;
    }
    sort(v.begin(),v.end(),cmp);
    (10)向量的大小
    size()方法和empty()方法
    v.size()和v.empty()。

    /************************************************************************************************/
    string 容器简介:
    (1)创建string对象
    string s;//初试长度为0
    (2)给string对象赋值
    法1:s="sjdjfj';
    法2:char ss[20];
    scanf("%s",ss);
    s=ss;
    (3)string对象尾部添加字符
    s=s+'a';
    (4)string对象尾部添加字符串
    法1:s=s+"abc";
    法2:s.append("abc");
    (5)string对象插入字符
    string::iterator it=s.begin();
    s.insert(it+1,'a');
    (6)访问string对象元素
    s="acffggg";
    cout<<s[0];
    (7)删除string对象的元素
    1.清空字符串可以直接赋值空字符串即可;
    2.使用erase()方法删除迭代器所指的那个元素或者那个区间所有元素;
    string s="aaaaffggg";
    string::iterator it=s.begin();
    s.erase(it+1);
    s.erase(it+1,it+4);
    (8)返回string对象的长度以及判断是否为空
    s.length()及s.empty();
    (9)替换string中的字符
    s.replace(3,3,"gppg");//从第三个字符开始将连续的3个字符替换为"gppg"
    (10)搜索string对象的元素或者子串
    采用find()方法:查找一个字符用单引号‘’界定;查找一个字符串用双引号""界定。
    s.find('c');
    s.find("sdd");
    (11)string对象的比较
    string对象可以用compare()方法与其它字符串进行比较,如果它比对方大,则返回1;如果它比对方小,则返回-1;
    如果它与对方相同,则返回0.
    s.compare("ssfgg");
    (12)反向排序string对象
    reverse()方法:头文件#include<algorithm>
    reverse(s.begin(),s.end());
    (13)string对象作为 vector元素
    vector<string>v;
    v.push_back("jack");
    v.push_back("shfj");
    cout<<v[0]<<v[1]<<endl;
    cout<<v[0][0]<<endl;
    cout<<v[0].length()<<endl;

    (14)string对象与字符数组互操作
    char ss[100];
    scanf("%s",ss);
    s=ss;
    printf(s.c_str());
    cout<<endl;
    printf("%s",ss);
    (15)string对象与sscanf函数
    string s1,s2,s3;
    char sa[100],sb[100],sc[100];
    sscanf("abc 123 pc","%s %s %s",sa,sb,sc);
    s1=sa;
    s2=sb;
    s3=sc;
    cout<<s1<<' '<<s2<<' '<<s3<<endl;
    int a,b,c;
    sscanf("1 2 3","%d %d %d",&a,&b,&c);
    cout<<a<<' '<<b<<' '<<c<<endl;
    int x,y,z;
    sscanf("4,5$6","%d,%d$%d",&x,&y,&z);
    cout<<x<<' '<<y<<' '<<z<<endl;
    (16)string对象与数值相互转换
    #include<iostream>
    #include<vector>
    #include<sstream>
    #include<string>
    using namespace std;

    string convertToString(double x)
    {
    ostringstream o;
    if(o<<x) return o.str();//将变量x读取到字符流o中
    return "error";
    }

    double convertFromString(const string &s)
    {
    istringstream i(s);
    double x;
    if(i>>x) return x;//相当于把字符串从字符流中读取到变量x中
    return 0.0;
    }
    int main()
    {
    char b[10];
    string a;
    sprintf(b,"%d",1975);
    a=b;
    cout<<a<<endl;
    string cc=convertToString(1976);
    cout<<cc<<endl;
    string dd="2006";
    int p=convertFromString(dd)+2;
    cout<<p<<endl;
    return 0;
    }

    /***************************************************************************************************/
    set集合容器(红黑树原理)
    (1)创建set集合对象
    set<int>s;
    (2)元素的插入和中序遍历,反向遍历(使用前向迭代器)
    #include<set>
    #include<iostream>
    using namespace std;
    int main()
    {
    set<int>s;
    s.insert(8);
    s.insert(1);
    s.insert(12);
    s.insert(6);
    s.insert(8);//重复,不执行插入操作
    set<int>::iterator it;
    for(it=s.begin();it!=s.end();it++)//正向遍历
    cout<<*it<<endl;
    set<int>::reverse_iterator rit;//反向遍历
    for(rit=s.rbegin();rit!=s.rend();rit++)
    {
    cout<<*rit<<endl;
    }
    return 0;
    }
    (3)元素的删除
    #include<set>
    #include<iostream>
    using namespace std;
    int main()
    {
    set<int>s;
    s.insert(8);
    s.insert(1);
    s.insert(12);
    s.insert(6);
    s.insert(8);//重复,不执行插入操作
    s.erase(6);//删除元素6(键值)
    set<int>::reverse_iteerator rit;
    for(rit=s.rbegin();rit!=s.rend();rit++)
    cout<<*rit<<endl;
    cout<<s.size()<<endl;
    return 0;
    }
    (4)元素的检索
    使用find()方法进行搜索,查到以后返回该键值在迭代器中的位置,否则返回最后一个元素后面的一个位置,即end()。
    set<int>::iterator it;
    it=s.find(6);
    if(it!=s.end()) cout<<*it<<endl;
    (5)自定义比较函数
    案例1:
    #include<set>
    #include<iostream>
    using namespace std;
    struct mycomp
    {
    bool operator()(const int &a,const int &b)
    {
    return a>b;
    }
    };
    int main()
    {
    set<int,mycomp>s;
    s.insert(3);
    s.insert(7);
    s.insert(11);
    s.insert(12);
    set<int,mycomp>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    {
    cout<<*it<<endl;
    }
    return 0;
    }
    案例2:
    #include<set>
    #include<iostream>
    using namespace std;
    struct info
    {
    string name;
    float score;
    bool operator<(const info &a)const
    {
    return a.score<score;
    }
    };
    int main()
    {
    set<info>s;
    info ifo;
    ifo.name="dd";
    ifo.score=999;
    s.insert(ifo);
    ifo.name="ss";
    ifo.score=799;
    s.insert(ifo);
    set<info>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    cout<<*it<<endl;
    return 0;
    }
    multiset多重集合容器(可重复元素的红黑树原理)
    (1)multiset元素的插入(头文件依然是#include<set>)
    #include<set>
    #include<string>
    #include<iostream>
    using namespace std;
    int main()
    {
    multiset<string>s;
    s.insert("aad");
    s.insert("bbc");
    multiset<string>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    cout<<*it<<endl;
    return 0;
    }
    (2)multiset元素的删除
    采用erase()方法可以删除multiset对象中的某个迭代器位置上的元素,某段迭代器区间中的元素,键值等于某个值的所有重复元素,并返回删除元素的个数。采用clear()方法可以清空元素。
    #include<set>
    #include<string>
    #include<iostream>
    using namespace std;
    int main()
    {
    multiset<string>s;
    s.insert("ssjj");
    s.insert("ssjj");
    s.insert("dggh");
    multiset<string>::iterator it;
    int n=s.erase("ssjj");
    for( it=s.begin();it!=s.end();it++)
    cout<<*it<<endl;
    return 0;
    }
    (3)查找元素
    find方法查找元素如果找到,返回该元素的迭代器位置(如果元素重复,返回第一个重复元素的迭代器位置);如果没有找到,则返回end()迭代器位置。
    #include<set>
    #include<string>
    #include<iostream>
    using namespace std;
    int main()
    {
    multiset<string>s;
    s.insert("abc");
    s.insert("def");
    s.insert("hgjj");
    multiset<string>::iterator it;
    it=ms.find("abc");
    if(it!=s.end())
    cout<<*it<<endl;
    return 0;
    }

    /******************************************************************************************/
    map容器简介
    map容器的数据结构采取的是红黑树来实现的,插入元素的键值不允许改变,比较函数只对元素的键值进行比较。

    (1)创建map对象
    键值与映照数据的类型自己定义。
    #include<map>
    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
    map<string,float>m;
    m["jack"]=98.5;
    m["bomi"]=96;
    m["kagr"]=67;
    map<string,float>::iterator it;
    for(it=m.begin();it!=m.end();it++)
    cout<<(*it).first<<' '<<(*it).second<<endl;
    return 0;
    }
    (2)删除元素
    采用erase()函数可以删除一个元素,一段元素,键值重复的元素。
    #include<iostream>
    #include<string>
    #include<map>
    int main()
    {
    map<int,char>s;
    s[1]='a';
    s[20]='t';
    s[15]='v';
    s.erase(20);
    map<int,char>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    cout<<(*it).second<<endl;
    return 0;
    }
    (3)元素的反向遍历
    使用迭代器reverse_iterator反向遍历和rbegin(),rend()方法进行遍历。
    #include<map>
    #include<string>
    #include<iostream>
    using namespace std;
    int main()
    {
    map<int,char>s;
    s[1]='a';
    s[2]='b';
    s[20]='f';
    map<int,char>::reverse_iterator rit;
    for(rit=s.rbegin();rit!=s.rend();rit++)
    cout<<(*rit).first<<' '<<(*rit).second<<endl;
    return 0;
    }
    (4)元素的搜索
    使用find()方法搜索某个键值,搜索到以后返回所在的迭代器位置,否则返回end()迭代器位置。
    法1:
    #include<map>
    #include<string>
    #include<iostream>
    using namespace std;
    int main()
    {
    map<int,char>s;
    s[1]='a';
    s[2]='b';
    s[20]='f';
    map<int,char>::iterator it;
    it=s.find(2);
    if(it!=s.end())
    cout<<(*it).first<<' '<<(*it).second<<endl;
    return 0;
    }
    (5)自定义比较函数
    默认函数排序是按照键值从小到大的顺序插入元素
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    struct mycomp
    {
    bool operator()(const int &a,const int &b)
    {
    return a>b;
    }
    };
    int main()
    {
    map<int,char,mycomp>m;
    m[25]='m';
    m[28]='f';
    m[10]='a';
    map<int,char,mycomp>::iterator it;
    for(it=m.begin();it!=m.end();it++)
    {
    cout<<(*it).first<<' '<<(*it).second<<endl;
    }
    return 0;
    }
    法2:
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    struct info
    {
    string name;
    float score;
    bool operator<(const info &a)const
    {
    return a.score<score;
    }
    };
    int main()
    {
    map<info,int>m;
    info ifo;
    ifo.name="sdj";
    ifo.score=80;
    m[ifo]=25;
    map<info,int>::iterator it;
    for(it=m.begin();it!=m.end();it++)
    {
    cout<<(*it).second;
    cout<<((*it).first).name<<' '<<((*it).first).score<<endl;
    }
    return 0;
    }
    Application:
    1.map容器实现数字分离
    #include<string>
    #include<map>
    #include<iostream>
    int main()
    {
    map<char,int>m;
    for(int i=0;i<10;i++)
    {
    m['0'+j]=j;
    }
    string sa;
    sa="asddddd";
    int sum=0;
    for(int i=0;i<sa.length();i++)
    sum+=m[sa[i]];
    cout<<sum<<endl;
    return 0;
    }
    2.map容器实现数字印照字符
    #include<iostream>
    #include<map>
    #include<string>
    int main()
    {
    map<int,char>m;
    for(int i=0;i<10;i++)
    m[j]='0'+j;
    string a="the number is:";
    cout<<s+m[7]<<endl;
    return 0;
    }


    /******************************************************************************************************/
    multimap容器简介
    (1)元素的插入
    #include<iostream>
    #include<map>
    #include<string>
    using namespace std;
    int main()
    {
    mmultimap<string,double>m;
    m.insert(pair<string,double>("jack",300.5));
    m.insert(pair<string,double>("lan",5868));
    m.insert(pair<string,double>("hdhf",6886));
    multimap<string,double>::iterator it;
    for(it=m.begin();it!=m.end();it++)
    cout<<(*it).first<<' '<<(*it).second<<endl;
    return 0;
    }


    (2)元素的删除
    #include<iostream>
    #include<map>
    #include<string>
    using namespace std;
    int main()
    {
    multimap<string,double>m;
    m.insert(pair<string,double>("jack",300.6));
    m.insert(pair<string,double>("jsjjd",300.56));
    m.insert(pair<string,double>("djj",384));
    m.erase("jack");
    multimap<string,double>::iterator it;
    for(it=m.begin();it!=m.end();it++)
    cout<<(*it).first<<' '<<(*it).second<<endl;
    return 0;
    }
    (3)元素的查找
    采用find()方法,如果找到则返回第一个键值的下标,否则返回end()迭代器位置。


    /******************************************************************************************/
    list双向链表容器
    list每个节点有三个域:前驱元素指针域,数据域,后继元素指针域
    对于迭代器只能通过“++”或者“--”的操作将迭代器移动到后继/前驱节点上,不能执行操作"+n"或者"-n";
    (1)创建list对象
    1.创建空链表:list<int>m;
    2.创建具有n个元素的链表:list<int>m(10);
    (2)元素的插入与遍历
    采用push_back(),push_front(),insert()方法进行。
    #include<list>
    #include<iostream>
    using namespace std;
    int main()
    {
    list<int>m;
    m.push_back(2);
    m.push_back(6);
    m.push_front(9);
    list<int>::iterator it;
    it++;
    m.insert(it,20);
    for(it=m.begin();it!=m.end();it++)
    cout<<(*it)<<endl;
    return 0;
    }
    (3)反向遍历
    采用反向迭代器reverse_iterator加rbegin(),rend()方法进行反向遍历
    (4)元素删除
    1.使用remove()方法删除链表中一个元素值相同的元素都会被删除;
    2.使用pop_front()和pop_back()方法进行删除首尾元素;
    3.使用erase()方法删除迭代器位置上的元素;
    list<int>::iterator it;
    it=s.begin();
    it++;
    s.erase(it);
    4.使用clear()方法清空list
    (4)元素查找
    使用find()方法查找:
    list<int>::iterator it;
    it=find(l.begin(),l.end(),7);
    if(it!=l.end())
    cout<<*it<<endl;
    (5)元素排序
    使用sort()方法
    (6)剔除连续重复元素
    使用unique()方法

    /**************************************************************************************/
    priority_queue优先队列容器
    push():插入元素
    pop():删除元素
    top():读取队首元素
    empty():是否为空
    size():读取元素数量
    重载<操作符定义优先级
    struct info
    {
    string name;
    float score;
    bool operator<(const Info &a)const
    {
    return a.score<score;
    }
    };
    priority_queue<info>q;

    重载“()”操作符定义优先级
    struct mycomp
    {
    bool operator()(const int &a,int &b)
    {
    return a>b;//这里与其它容器相反,>表示从小到大排列,<表示从大到小排列
    }
    };

  • 相关阅读:
    使用thinkphp连接sqlserver数据库时提示“系统不支持:sqlsrv”
    ThinkPHP连接sql server数据库
    帝国cms常用变量总结
    帝国CMS常见问题记录
    帝国CMS商城功能高级使用
    帝国CMS 6.0功能解密之新版结合项功能,帝国结合项使用
    CSS媒体查询,CSS根据不同的分辨率显示不同的样式
    使用phpstuby时,Apache或mysql无法启动,端口被占用
    火狐firefox提示“内容编码错误 无法显示您尝试查看的页面,因为它使用了无效或者不支持的压缩格式。”
    js跳转页面方法整理
  • 原文地址:https://www.cnblogs.com/khbcsu/p/4271332.html
Copyright © 2020-2023  润新知