• string,vector和array(C++ Primer读书笔记)


    string

    string是标准库类型,使用时需要包涵头文件,使用using声明。

    include <string>
    using std::string;

    1.定义和初始化

    string s1;
    string s2(s1);
    string s2 = s1;
    string s3("value");
    string s3 = "value";
    string s4(n, 'c');//把s4初始化为连续n个字符c组成的串

    2.操作

    getline(is, s);//从is中读取一行附给s,返回is。例如getline(cin,s);
    s.empty();     //s为空返回true,否则返回false
    s.size();      //返回s中字符个数

    还可以对string使用[],+,=,==,!=,<,>,<=,>=(字典序比较)等运算符。
    用cin读取string对象时,会忽略前面的空白,读到正真的字符到空白为止。
    getline注意一下,它读入一行,如果想读入的字符串有空格就不能直接用cin读入,这时可以使用getline。getline会读入换行符,但是读入的字符串并不包含回车符

    3.string::size_type类型

    size函数的返回值是string::size_type类型。
    可以通过auto(auto len=line.size();)或decltype(decltype(s.size()) cnt=0)
    注意:"Hello"+"world";这个语句是错的,因为字符串字面值不是string类型,不能直接想加。但是”Hello”+string是可以的。

    4.cctype头文件中的函数

    isalnum(c);     //当c是字母或数字时为真
    isalpha(c);     //字母    
    isdigit(c);     //数字
    islower(c);     //小写字母
    isupper(c);     //大写字母
    ispunch(c);     //标点符号
    isspace(c);     //空白
    tolower(c);     //大写变小写
    toupper(c);     //小写变大写

    5.范围for(range for)

    for (auto c : str)
        cout << c << endl;

    一段测试代码。

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
        string str1, str2, str;
        cout << "cin读入字符串只能读到空格~" << endl;
        cin >> str1;
        cout << str1 << endl;
        cin.sync();     //清空输入缓冲区
        cout << "getline可以读入一行~" << endl;
        getline(cin, str2);
        cout << str2 << endl;
        //-----size()函数返回string::size_type类型,可以用auto或decltype来声明
        cout << "用for循环遍历str2" << endl;
        for (string::size_type i = 0; i < str2.size(); i++)
        {
            cout << str2[i] << " ";
        }
        cout << endl;
        //-----string对象可以直接相加
        cout << "string对象可以直接相加,比如~" << endl;
        str = str1 + str2;
        cout << str << endl;
        //----范围for
        cout << "用范围for遍历string" << endl;
        for (auto &ch : str)
        {
            //这里也许需要注意一下,变量必须是在for内声明,比如char ch; for(ch : str)这样是错的编译不会通过。
            ch = toupper(ch);
        }
        cout << str << endl;
        return 0;
    }
    

      

    vector

    vector是类模板。
    用法样例:vector<int> ivec; vector<vecrot<string>> file;
    过去(C++ 11之前)定义必须写成 vector<vecrot<string> /*这里是一个空格*/> file;

    1.初始化

    vector<T> v1;       //一个空的vector对象
    vector<T> v2(v1);
    vector<T> v2 = v1;
    vector<T> v3(n, val);
    vector<T> v4(n);    //n个元素,默认初始值
    vector<T> v5{a, b, c...};
    vector<T> v5={a, b, c...};

    2.操作

    v.pash_back(val);//把元素val添加到vector的尾端。如果vector<int> v(n),那么v.push_back()是从第n+1个数开始加的,即v[n]
    v.empty();
    v.size();
    v[n];
    v1 == v2;//v1和v2元素数量相等,且每一个值都相同
    v1 != v2;
    <, <=, >, >=

    3.迭代器
    begin成员负责返回指向第一个元素的迭代器
    end成员负责返回指向容器“尾元素的下一位置”的迭代器,没有实际意义,仅起标记作用,常称为尾后迭代器

    有关push_back();

    vector<int> vec(10);
    for(vector<int>::size_type i = 0; i != vec.size(); i++){
        vec.push_back(i);
    }

    这是死循环,因为vec.size()随循环边长~同理,范围for中也不要加入尝试添加元素。同时可能改变vector对象容量的操作,会使该对象迭代器失效。

    vector初始化小测试,orz我的编译器不支持C++11

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    void print(vector<int> vec)
    {
        for (vector<int>::iterator ip = vec.begin(); ip != vec.end(); ip++)
        {
            cout << *ip << " ";
        }
        cout << endl;
    }
    
    int main()
    {
        vector<int> vec1(10);
        print(vec1);
        vector<int> vec2(10, 8);
        print(vec2);
        vector<int> vec3{10, 8};
        print(vec3);
        vector<int> vec4(vec3);
        vec4.push_back(6);
        print(vec4);
    
        return 0;
    }
    

      

    输出结果为
    0 0 0 0 0 0 0 0 0 0
    8 8 8 8 8 8 8 8 8 8
    10 8
    10 8 6

    练习题3.17(很好奇为什么有push_back没有删除,于是搜到了erase,试着用了一下。

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    int main()
    {
        vector<string> vec;
        string str;
        while (cin >> str)
        {
            vec.push_back(str);
        }
        for (vector<string>::iterator ip = vec.begin(); ip != vec.end(); ip++)
        {
            if (*ip == "yi")
            {
                vec.erase(ip);
            }
        }
        for (vector<string>::iterator ip = vec.begin(); ip != vec.end(); ip++)
        {
            for (char &ch : *ip)
            {
                ch = toupper(ch);
            }
            cout << *ip << " ";
            cout << endl;
        }
    
        return 0;
    }
    

      

    输入:
    yi shan yi shan liang jing jing
    输出:
    SHAN
    SHAN
    LIANG
    JING
    JING
    ”后来才发现有问题,懒得改了,因为在循环中删除元素,导致迭代器错误。比如输入yi yi er yi yi er 就会输出YI ER YI ER 循环中改成if (*ip == "yi") { vec.erase(ip); --ip; }会好吧。

    练习题3.26
    值得注意,因为窝自己就写成了mid = (beg + end) / 2;结果出错。因为并没有重载iterator之间的加法。
    写成mid = beg + (end - beg) / 2;
    到做题时有人也这么写,我嫌麻烦从来都是(l + r) >> 2,突然意识到也许他们是防止数据太大溢出(捂脸

    数组

    数组在c语言都学过的就一眼带过了。
    数组的下标是size_t类型(一直以为unsigned int啊喂)在cstddef头文件中定义。
    指针也是迭代器。
    通过函数begin()和end()返回指向数组首元素和尾元素的下一位置的指针。参数为数组。

    ptrdiff_t n = end(arr) - begin(arr);    //n即为arr中的元素

    ptrdiff_t为标准库类型,定义在cstddef头文件中。它的空间足够大,能表示数组中任意两个指针之间的距离。

    #include <iostream>
    using namespace std;
    
    int main() {
        char arr[10];
        cin >> arr;
        for (auto i = begin(arr); i != end(arr); i++){
            cout << *i << " ";
        }
        cout << "there are " << end(arr) - begin(arr) << " elements";
        return 0;
    }
    

      

    输入:1234567
    输出:1 2 3 4 5 6 7   there are 10 elements

    可以用数组初始化vector对象。
    例:

    int int_arr[] = {0, 1, 2, 3, 4, 5};
    vector<int> ivec(begin(int_arr), end_arr(int_arr));
    vector<int> subVec(int_arr + 1, int_arr + 4);

    通过函数c_str();可以将string返回一个字符数组(C风格字符串)。返回值为const char*类型。如果后续一直想用该数组,最好拷贝一份。
    用范围for遍历二维数组

    #include <iostream>
    using namespace std;
    
    int main() {
        int arr[][3] = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}, {}, {9, 7, 8}};
        for (const auto &row : arr){
            for (auto col : row)
                cout << col << " ";
            cout << endl;
        }
        return 0;
    }
    

      

    如果row不加&的话会编译出错(error: ‘begin’ was not declared in this scope for (auto col : row)),原因是不声明为引用类型,row数组会自动转化为指针int *。

    类性别名简化多维数组的指针

    using int_array = int[4];
    typedef int int_array[4];//这两个语句等价,将类型“4个整数组成的数组”命名为int_array。
  • 相关阅读:
    ajax-分页查询
    Bootstrap-响应式表格
    ajax-三级联动
    ajax(加载数据)
    HDU 3086 马拉车模板
    Power Strings POJ2406 KMP 求最小循环节
    KMP模板题 Number Sequence HDU1711
    Phone List HDU1671 字典树Trie
    一些linux"基本操作"的教程汇总
    Codeforces 899F Letters Removing 线段树/树状数组
  • 原文地址:https://www.cnblogs.com/wenruo/p/4492694.html
Copyright © 2020-2023  润新知