• C++学习2 字符串、向量和数组


    C++学习2 字符串、向量和数组

    string表示可变长的字符串序列,vector存放的是某种给定类型对象的可变长序列。

    命名空间的using声明

    域作用符(::)用来将命令空间中的函数或对象进行调用。
    可以使用using声明来使得可以直接访问命名空间或者命名空间中的某个函数。

    using std:cin;    //这样就可以直接调用cin函数

    可变长字符序列之string库

    使用string库之前必须先包括其头文件和作用域。

    #include<string>
    using std::string;

    定义和初始化string对象

    分为直接初始化和拷贝初始化.

    string s1; //默认为空字符串
    string s2(s1); //s2为s1的副本
    string s3="liangzi"; //拷贝初始化
    string s4(s3); //s4时s3的副本
    string s4=s3;//与上一条指令等价
    string s5("liangzi");//直接初始化
    string s6(100,'cc'); //将cc重复100遍得到的字符串

    string对象上的操作

    os<<s   //将s中的字符串写到输出流os之中,返回os
    is>>s //与上一条指令相似,将输入的字符串存储到s之中
    is=getline(is, s)   //该函数将从is中读取一行赋值给s,之后返回is
    s.empty()  // 判断字符串是否为空
    s.size()  //返回字符串中字符的个数
    s[n]   //返回字符串中的第n个字符,从0开始
    s1+s2 //两个字符串进行连接
    s1==s2 //二者完全一致
    <, <=, >, >= //利用字符在字典中的顺序进行比较

    下面给出一个读写string对象的简单例子。

    int main()
    {
        string s;
        cout << "please input a string" << endl;
        cin >> s;
        cout << s << endl;
        return 0;
    }

    使用getline读取一整行

    与cin不同,如果一开始的输入是一个换行符,getline函数读取之后会得到一个空字符。
    使用示例

    int main()
    {
    
    //使用C++读取文本文件的示例
        string file_path, line;
        fstream read_file;  //文件流类型,以后会详细介绍
        cout << "please input the need read path" << endl;
        cin >> file_path;
        read_file.open(file_path);
        while (!read_file.eof())
        {
            getline(read_file,line);
            cout << line << endl;
        }
        read_file.close();
        system("pause");
        return 0;
    }

    字符串常量和string对象相加

    必须注意C++中“+”左右至少有一个string对象,即两个字符串常量不能进行相加操作。

    string s1="liangzi", s2="zuishuai";
    string ss=s1+s2;                                //正确
    string sss=s1+"---------->>"+s2;         //正确
    string ssss="liangzi"+"zuishuai";       //错误

    对string对象中的字符进行处理

    首先介绍一下c语言库中的一些常用函数

    cctype(或ctype.h)

    #incldue<cctype>
    using std::cctype;
    
    isalnum(c)  //当c为字母或者数字时为真
    isalpha(c)  //当c为字母时为真
    iscntrl(c)   //当c为控制字符时为真
    isdigit(c)   //当c为数字时为真
    isgraph(c) //当c不是空格但是可以打印时为真
    islower(c) //当c是小写字母时为真
    isprint(c)  //当c是可打印字符时为真
    ispunct(c)  //当c是标调符号时为真
    isspace(c)  //当c是空白时为真
    isupper(c)  //当c为大写字母时为真
    isxdigit(c)  //当c是十六进制数字时为真
    tolower(c)  //若c为大写字母,将其变为小写字母,否则不变
    toupper(c) //若c为小写字母,将其变为大写字母,否则不变

    使用基于范围的for语句来遍历string对象中的每一个字符

    范围for语句(range for)是c++11中提出的,这种语句可以实现对给定序列中的每一个值进行处理。

    //例如,输出一个字符串的每一个字符
    sting s("liangzid");
    for(auto i:s)
    {
        cout<<i<<endl;
    }

    再给出一个统计标点符号的示例。

    string s("liangzi zi zui shuai ! ");
    i=0;
    for (auto &c:s)
    {
        if (ispunct(c))
        {
            ++i;
        }
    }
    cout<<" the number of punctuation characters is : "<<i<<endl;

    标准库类型vector

    标准库类型vector表示同一类型的若干对象的集合,且集合中的每一个对象都有一个对应的索引。因为该向量(vector)容纳着这些对象,所以说vector也被称作是容器(container)。后面将会对容器进行更详细的介绍。

    C++中既有类模板(class template),也有函数模板。模板本身不是类和函数,模板相当于是编译器为了生成类或者函数而编写的一份说明。编译器根据模板创建类或者函数的过程被称为实例化(instantiation)

    对于类模板,需要添加一些额外信息以确定模板到底实例化成什么样的类,一般来说,提供信息的方式为:再模板后面跟一对尖括号,里面放上相应的信息。

    vector是一个类模板。
    注释:在c++11中,两层vector的话必须在最后的两个尖括号处放置空格,即vector<vector<int> >而非vector<vector<int>>

    定义和初始化vector对象

    与string的定义和初始化类似,vector的用法如下:

    vector<Type> v1       //v1是一个空的容器,执行Type类型的默认初始化
    vector<Type> v2(v1)  //v2是v1的副本
    vector<Type> v3=v1  //直接初始化
    vector<Type> v4(n,val)  //v4包括了n个重复的均为val的元素
    vector<Type> v5{a,b,c,...}  //v5中容纳的元素包括a,b,c,...
    vector<Type> v6={a,b,c,...}//同上

    向vector对象中添加元素

    使用 push_back() 函数来将一个元素压入vector对象的尾端。

    //示例:初始化一个数列,里面储存着从0到99的整数
    vector<int> sequence;
    for(int i=0;i !=100;i++)
    {
        sequence.push_back(i);
    }
    //使用示例:将之前读取的没一行作为一个元素,实现对任何不定长文件的动态储存。
    int main()
    {
       string file_path, line;
       fstream read_file;
       vector<string> all_lines;
       cout << "please input the need read path" << endl;
       cin >> file_path;
       read_file.open(file_path);
       while (!read_file.eof())
       {
       	getline(read_file,line);
       	all_lines.push_back(line);
       }
       read_file.close();
       system("pause");
       return 0;
    }

    vector的其他使用注意

    和使用string一样,也可以使用范围for语句进行处理。
    比如对前面读取得到的vector向量进行逐元素的输出,则可以使用range for语句。

    int main()
    {
        string file_path, line;
        fstream read_file;
        vector<string> all_lines;
        cout << "please input the need read path" << endl;
        cin >> file_path;
        read_file.open(file_path);
        while (!read_file.eof())
        {
            getline(read_file,line);
            all_lines.push_back(line);
        }
        read_file.close();
        for (auto &cc : all_lines)
        {
            cout << cc << endl;
        }
        system("pause");
        return 0;
    }
    

    同样地,我们可以使用下标索引来访问vector<Type> CC中的每一个元素,但是无法用下标来创造一个新的元素。

    迭代器(iterator)

    迭代器是一种机制(可以看作是一种类型),类似于指针类型,迭代器提供了对对象进行间接访问的方式。迭代器可以间接访问容器中的某个元素或者string对象中的某一个字符。迭代器可以访问某个元素,也可以从一个元素移动到另外一个函数。迭代器有有效无效之分,与指针相同,当迭代器指向某个元素或者尾元素的下一个位置时迭代器有效,其他情况均为无效。

    使用iterator

    一般利用beginend来进行对容器的指向。begin成员负责返回第一个元素(或字符)的迭代器,end用来返回指向容器尾元素的下一个位置的迭代器——即该迭代器标记了容器的一个根本不存在的”尾后“(off the end)元素,用来表示我们已经处理完了容器中的所有元素。end成员返回的迭代器通常被称为**尾后迭代器(off-the-end iterator)**或尾迭代器(end iterator)。如果容器为空,则begin与end均返回尾迭代器。
    详细见示例。

    vector<int> liangzi{1,2,3,4,5};
    auto begin_liangzi=liangzi.begin();
    auto end_liangzi=liangzi.end();
    //之所以使用auto,是因为我们也不确定到底其指定的是什么类型

    iterator运算符

    //通过以下运算符可以看出迭代器和指针的类似之处
    
    *iter                                   //返回迭代器iter所指向元素的引用
    iter->mem                        //解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem
    ++iter                                 //令iter指向容器中的下一个元素
    --iter                                 //令iter指向容器中的上一个元素
    iter1==iter2                //若相等,指它们指向了容器中的同一个元素
    iter1 != iter2                  //同上 

    迭代器的运算部分

    数组

    数组是一种类似于vector的数据结构,但是数组的长度是固定的。数组在提高了一点性能的同时丧失了一点灵活性。

    定义和初始化内置数组

    定义数组时必须指定数组的类型(不能使用auto),定义数组时中括号里的量一定要是常量或者常量表达式。不能使用一个数组对另外一个数组进行初始化。

    int i=100;      //不是常量表达式
    constexpr int ii=100;
    int array1[100];                       //正确
    int *parray[100];                      //正确,数组中的每个元素都是指向整型数据的指针
    string array2[i];                      //错误
    string array3[ii];                        //正确
    
    int a[ ]={1,2,3};
    int aa[ ]=a;            //错误
    
    int &liangzi[100]={1,2,3,...};                //错误,引用不是一个对象,不能被数组储存
    
    int *pliangzi[100];                          //正确,数组中的每个圆度都是指针
    int (*pliangzii)[100]=&array1;                   //正确,定义了一个指针,指向一个有100个元素的数组
    int (&liangzia)[100]=array;                      //正确,是对一个数组的引用
    
    /* 可以记住一句口诀:从右向左,从内向外*/

    访问数组元素

    使用下标访问

    指针和数组的关系

    与C语言中相似,数组名即是一个指向数组中第一个元素的指针。试图定义一个指针指向数组中的某一个元素,可以使用

    int a[100];
    int *p=&a[20]; 

    也可以使用

    int *p2=a;

    对于指针也相当于迭代器,c++11特别引入了两个函数begin()和end()来描述一个数组的首端和尾后。有

    int array[10];  
    int *parray=&array[10];         //尾后指针,不能进行解引用,也不能进行递增
    int *begin_array=begin(array);        //下指向首元素的指针,相当于array
    int *end_array=end(array);             //尾后指针

    多维数组

    严格来说并不存在多维数组,多维数组表达的意义是数组的嵌套。比如说二维数组就是一个数组的数组。

    在理解多维数组时,越靠近自变量名字的下标代表越基本的元素分布。比如int a[2][3][4];就代表有一个数组,长度为2,其中的每一个元素都包含着三个元素,这三个元素每一个都是一个长度为4的数组。

    多维数组的初始化

    与python的numpy类似,但是此处使用花括号。

    int ia[3][4]={
    {1,2,3,4},
    {5,6,7,8},
    {1,2,3,4}
    };

    当然,由于多维数组本质上是由1维数组表示的,所以也可以采用直接的一长串来表示。

    多维数组的下标引用

    可以使用下标运算符来访问多维数组的元素。当下标的数目少于数组本身的维度时,返回的是一个差值维度的数组。

    int ra[3][4];
    int arr[3][4][5];
    
    ra[2][3]=arr[0][0][0];       //元素之间的赋值操作
    int (&row)[4]=ra[1];        //row是对一个长度为4的数组的引用

    利用range for 处理多维数组

    以二维数组为例进行说明。

    //实现对二维数组中的所有元素进行求和
    sum=0;
    for (auto &i:array)
       for (auto &j:i)
       {
       	sum+=j;
       }
  • 相关阅读:
    memory prefix out omni,over,out,od,octa ~O
    killl prefix out macro mis mal micro -m
    memory prefix mini mono multi out _m 5
    memory prefix inter,intra,intro,iso out 5
    memory prefix il ir im in out 3 i
    memory prefix twi,tri,trans ,tetra out 4
    memory prefix retro,re out 2
    memory prefix un,under,uni out1
    Python调用libsvm
    yolov3 训练数据集
  • 原文地址:https://www.cnblogs.com/liangzid/p/10910120.html
Copyright © 2020-2023  润新知