zoukankan      html  css  js  c++  java
  • STL心得

    • 熟悉c++版算法竞赛程序框架
    • 理解变量引用的原理
    • 熟练掌握string和stringstream
    • 熟练掌握c++结构体的定义和使用,包括构造函数和静态成员变量
    • 了解常见的可重载运算符,包括四则运算,赋值,流式输入输出,()和 [ ]
    • 了解模板函数和模板类的概念
    • 熟练掌握stl中排序和检索的相关函数
    • 熟练掌握stl中vector,set,map这3个容器
    • 了解stl中的集合相关函数
    • 理解栈,队列和优先队列的概念,并用stl实现它们
    • 熟练掌握随机数生成方法,并能结合assert宏进行测试
    • 能独立编写大整数类BigInteger

     


    ·string

    标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件。

    初始化string对象

    使用等号初始化实际上是拷贝初始化,不使用则为直接初始化。

    string s1;   //默认初始化,s1是一个空字符串
    
    string s2 = s1;      //s2是s1的副本
    
    string s3 = "hiya"; //s3的内容是该字符串字面值的副本
    
    string s4(10, 'c');  //s4的内容是cccccccccc

     

    string对象上的操作:

    os<<s  //将s写到输出流os当中,返回os
    
    is>>s //从is中读取字符串赋给s,字符串以空白分隔,返回is
    
    getline(is,s)  //从is中读取一行赋给s,返回is
    
    s.empty() //s为空返回true,否则返回false
    
    s.size()  //返回s中字符的个数
    
    s[n]  //返回s中第n个字符的引用,位置n从0记起
    
    s1+s2  //返回s1和s2连接后的结果
    
    s1 == s2  //用s2的副本替代s1中原来的字符
    
    s1!=s2  //等性判断对字母大小写敏感
    
    <, <=, >, >=  //利用字符在字典中的顺序进行比较,且对字母的大小写敏感

    读取未知数量的string对象

    在执行读取操作时,string会自动忽略开头的空白(即空格符,换行符,制表符等),并从第一个真正的字符开始读起,知道遇到下一处空白为止。 

    int main()
    {
        string word;
        while(cin >> word)  //反复读取,直至到达文件末尾
              cout  << word << endl;  //逐个输出单词,每个单词后面紧跟一个换行
      return 0;
    }

    使用getline读取一整行

    当我们希望在最终得到的字符串中保留输入时的空白符,这时应该用getline函数替代原来的>>运算符。getline函数的参数是一个输入流和一个string对象,函数从给定的输入流读入内容,直到遇到换行符为止(注意换行符也被读来了),然后把所读的内容存入到那个string对象中去(注意不存换行符)。getline只要一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始是换行符也是如此。如果输入的真的一开始就是换行符,那么所得到的结果是个空的string。

    可以通过改写之前的程序让它一次输出一整行而非每行一个单词了:

    int main()
    {
        string line;
    //每次读入一整行,直至到达文件末尾
        while(getline(cin,line))  
              cout  << line << endl;  
      return 0;
    }

    因为line中不包含换行符,所以我们手动加上换行符操作。和往常一样,使用endl结束当前行并刷新显示缓冲区。

    cctype头文件的函数:

    isalnum(c)   //当c是字母或数字时为true
    
    isalpha(c)   //当c是字母时为true
    
    isdigit(c)    //当c是数字时为true
    
    islower(c)  //当c是小写字母时为true
    
    isupper(c) //当c是大写字母为true
    
    isspace(c) //当c是空白时为true(即c是空格/制表符/回车符/换行符/进纸符之中的一种)
    
    ispunct(c) //当c是标点符号为true(即c不是控制字符/数字/字母/可打印空白之中的一种)
    
    tolower(c) //当c是大写字母,输出对应小写字母,否则原样输出
    
    toupper(c) //当c是小写字母,输出对应大写字母,否则原样输出

    只处理一部分字符:

    想要访问string对象中的单个字符有两个方式:一种是使用下标,另一种是使用迭代器。

    下标运算符([])接受的输入参数是表示要访问的字符的位置,返回值是该位置上字符的引用。string对象的下标 》0 && <s[s.size()] s[s.size()-1]是最后一个字符。

    ·string和stringstream区别 

       【定 义】:可以简单的这样理解,string是一种数据类型,而stringstream是针对string的一种数据流出或者流入的操作,相当于I/O操作。字符串流是通过空格判断一个字符串的结束 。需要记住:C++中可以使用流简化输入输出操作 

     【注 意】:

    • stringstream是字符串流,经常被我用来作数据切分(空格划分)或者类型转化字符串流主要还是用来遍历字串符的。一个简单的用法,如果一个字符串格式为 数字.数字.数字
      此字符串用来表示时间,若要取三个数字
      input >> a >> ch >> b >> ch >> c;即可。stringstream就是string流,把数据放进string或从string里取数据相当于c的sprintf/scanef。
    • 1.对stringstream对象使用>>操作符会改变对象保存的内容,会移除开头的一部分用分隔符隔开的字符串。 
      2.对stringstream对象使用str("")方法后对象变成“错误的指针”状态,此后必须要用clear()才能清除错误状态。 
      综上,使用clear方法才是正确的。
    【基本用法】:

    stringstream是字符串流。它将与存储在内存中的string对象绑定起来。
    在多种数据类型之间实现自动格式化。

    1.stringstream对象的使用
    #include<sstream>
    #include<iostream>
    using namespace std;
    int main()
    {
            string line,word;
            while(getline(cin,line))
            {
                    stringstream stream(line);
                    cout<<stream.str()<<endl;
                    while(stream>>word){cout<<word<<endl;}
            }
            return 0;
    }
    
    /*
    输入:shanghai no1 school 1989
    输出:shanghi no1 school 1989
         shanghai
        no1
        school
    */
        1989
    View Code


    2.stringstream提供的转换和格式化
    程序:

    #include<sstream>
    #include<iostream>
    using namespace std;
    int main()
    {
            int val1 = 512,val2 =1024;
            stringstream ss;
            ss<<"val1: "<<val1<<endl      //“val1: "此处有空格,字符串流是通过空格判断一个字符串的结束
         <<"val2: "<<val2<<endl;
            cout<<ss.str();
    
            string dump;
            int a,b;
            ss>>dump>>a
         >>dump>>b;
            cout<<a<<" "<<b<<endl;
            return 0;
    }
    
    输出为:val1: 512
        val2: 1024
        512 1024
    View Code

    第一处黑体字部分:将int类型读入ss,变为string类型
    第二处黑体字部分:提取512,1024保存为int类型。当然,如果a,b声明为string类型,那么这两个字面值常量相应保存为string类型

    3.其他注意
    stringstream不会主动释放内存(或许是为了提高效率),但如果要在程序中用同一个流,反复读写大量的数据,将会造成大量的内存消耗,因些这时候,需要适时地清除一下缓冲 (用 stream.str("") )

    #include <cstdlib>
    #include<iostream>
    #include<sstream>
    using namespace std;
    int main()
    {
            stringstream ss;
            string s;
            ss<<"shanghai no1 school";
            ss>>s;
            cout<<"size of stream = "<<ss.str().length()<<endl;
            cout<<"s: "<<s<<endl;
            ss.str("");
            cout<<"size of stream = "<<ss.str().length()<<endl;
    }
    
    输出:
    size of stream = 19
    s: shanghai
    size of stream = 0
    View Code
    
    

    ·在C++中,什么时候必须使用引用?C/C++何时使用引用和指针
    使用引用,就不用调用对象的拷贝构造函数,将对象本身传如函数里面,比如:
    void add(const A& a); // 这样传入的就是引用,调用此函数时,就是直接使用a
    void add(A a); // 这样传入的是对象的拷贝进去,需要构造这样的一个对象传递进去,效率没上面的高。


    ·
    顺序容器,常用的顺序容器头文件分别是:
    #include <vector>//不定长数组
    #include <map>//映射
    #include <set>//集合
    #include <list>//链表
    #include <deque>//*双向队列
    #include <queue>//队列
    #include <stack>//堆栈

    1.“不定长数组vector”

    声明方法:

    vector是一个模板类,所以需要用vector<int> a或者vector<double> b这样的方式来声明一个vector。vector(以及string对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素。

    vecto<int> a;
    
    a.size( ); //读取a的大小
    
    a.resize( ); //改变a的大小
    
    a.push_back( ); //向a的尾部添加元素
    
    a.pop_back( );  //删除a的最后一个元素
    
    a.clear( ); //清空a
    
    a.empty( ); //测试a是否为空
    vector<int> pile[maxn]

    还有点要说,这条语句定义了一个名称为pile的二维向量,有pile[1],pile[2]...pile[maxn]共maxn个,每个pile[n]代表一个木块堆,容量大小是可变的。

    2.“集合:set”

    声明方法:Sets are containers that store unique(唯一的)elements following a specific order.

    基本操作:

    
    #include <set>
    
    set<string> exclusion_set;
    
    exclusion_set.size();//获取exclusion_set的大小
    
    exclusion_set.empty();//清空exclusion_set
    
    exclusion_set.erase();//删除exclusion_set中的元素
    
    exclusion_set.find();//如果元素存在,则find()返回指向这个元素的
    iterator,否则返回一个等于end()的iterator表示该元素不存在 
    
    exclusion_set.count();//如果找到元素,count()返回1,如果元素不存在,则返回0   

     3.“映射:map”

    map与之前的set有一些相似之处,比如map的键值也具有独一性,任意两个不同的元素不能拥有相同的键值。所以插入可能失败,如之前所说,与set不同的是,map由键/值对构成,是从键(key)到值(value)的映射。

    声明方法:为定义map对象,我们至少要指明键和值的类型,例如:map<string, int> word_count;

    4. “可重复集合:multiset”

    set和multiset的区别在于set容器里不能有重复元素。a和b重复<=>“a必须排在b前面”和“b必须排在a前面”都不成立。

    定义了一个multiset变量st,st里面可以存放T类型的数据,并且自动排序。开始st为空。

    排序规则:表达式“a<b”为true,则a排在b前面。

    可用st.insert添加元素,st.find查找元素,st.erase删除元素,复杂度都为log(n)。

     
    #include<iostream>
    #include<cstring>
    #include<set>
    using namespace std;
    
    int main()
    {
        multiset<int> st;
        int a[10]={ 1,14,12,13,7,13,21,19,8,8 };
    
        for(int i = 0; i < 10; i++)
            st.insert( a[i] );   //插入的是a[i]的复制品
    
        multiset<int>::iterator i; //迭代器,近似于指针
        for(i = st.begin(); i != st.end(); i++)//不要重新int i !!!
            cout<< * i << ",";
        cout<<endl;
        return 0;
    }
    View Code
    
    
    
    
    




  • 相关阅读:
    salt+jenkins+gitlab+ecs构建公司部署平台
    解决openstack实例主机名后缀问题
    测试CentOS-7-x86_64-Minimal-1708.iso这种光盘安装效果
    dbca建库--linux上使用vnc图形化安装oracle10g版本
    使用mediainfo工具统计每个视频文件(媒体文件)播放时长
    rsync命令简单用法介绍
    winscp工具和xshell连接linux机器时切换到root账户
    zabbix和iptables的nat表结合使用
    adb和机顶盒一些常识
    VirtualBox虚拟机禁止时间同步
  • 原文地址:https://www.cnblogs.com/Roni-i/p/7359224.html
Copyright © 2011-2022 走看看