C++学习笔记总结练习:string字符串容器和泛型算法

1 string字符串容器和泛型算法

1.1 STL顺序容器

参考顺序容器部分

  • 访问元素
    • 也可以使用迭代器访问元素。
    • at会进行安全检查抛出异常。
    • []下标运算符不会进行检查。
    • back(),front()
  • 添加元素
    • 总共有6+3=9种插入方法。insert有额外的两种范围插入方法。
    • 在尾部添加元素push_back(),emplace_back()
    • 在头部添加元素push_front(),emplace_front()
    • 在中间添加元素insert(),emplace()
    • insert方法提供了范围插入的方法。中间插入一个元素。在给定的一个迭代器之前插入一个值。中间插入多个元素。在给定的迭代器之前插入范围迭代器内的元素。
  • 删除元素
    • back、front、push_back、push_front、pop_back、pop_front、emplace_front、emplace_back。是一组首尾相关的插入操作。
    • insert、emplace、at、erase。是一组随机的操作。
  • 重构容器
    • 并非该表容器内存的大小。而是改变容器范围的大小。

1.2 STL泛型算法

  • string 对象也可以看作一个顺序容器,它支持随机访问迭代器,也有 begin 和 end 等成员函数。STL 中的许多算法也适用于 string 对象。下面是用 STL 算法操作 string 对象的程序示例。
C++ 复制代码
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
    string s("afgcbed");
    string::iterator p = find(s.begin(), s.end(), 'c');
    if (p!= s.end())
        cout << p - s.begin() << endl;  //输出 3
    sort(s.begin(), s.end());
    cout << s << endl;  //输出 abcdefg
    next_permutation(s.begin(), s.end());
    cout << s << endl; //输出 abcdegf
    return 0;
}

2 string字符串操作

2.1 字符串创建

  • string 类有多个构造函数,用法示例如下:
    • 拷贝初始化
    • 序列初始化
    • 子串初始化

这三种初始化的恶魔是,在assign、find、append、replace、insert函数中,也在使用。就如同顺序容器中的初始化方法,在顺序容器的其他的操作中也是通用的。

C++ 复制代码
string s1();  // si = ""
string s2("Hello");  // s2 = "Hello"
string s3(4, 'K');  // s3 = "KKKK"
string s4("12345", 1, 3);  //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串
  • 为称呼方便,本教程后文将从字符串下标 n 开始、长度为 m 的字符串称为"子串(n, m)"。
  • string 类没有接收一个整型参数或一个字符型参数的构造函数。下面的两种写法是错误的:
C++ 复制代码
string s1('K');
string s2(123);

2.2 字符串赋值

  • 可以用 char* 类型的变量、常量,以及 char 类型的变量、常量对 string 对象进行赋值。例如:
C++ 复制代码
string s1;
s1 = "Hello";  // s1 = "Hello"
s2 = 'K';  // s2 = "K"
  • string 类还有 assign 成员函数,可以用来对 string 对象赋值。assign 成员函数返回对象自身的引用。例如:
C++ 复制代码
string s1("12345"), s2;
s3.assign(s1);  // s3 = s1
s2.assign(s1, 1, 2);  // s2 = "23",即 s1 的子串(1, 2)
s2.assign(4, 'K');  // s2 = "KKKK"
s2.assign("abcde", 2, 3);  // s2 = "cde",即 "abcde" 的子串(2, 3)

2.3 字符串交换

  • swap 成员函数可以交换两个 string 对象的内容。例如:
C++ 复制代码
string s1("West"), s2("East");
s1.swap(s2);  // s1 = "East",s2 = "West"

2.4 字符串长度

  • int length() 成员函数返回字符串的长度。
  • int size() 成员函数可以实现同样的功能。

2.5 字符串比较

  • 可以用 <、<=、==、!=、>=、> 运算符比较 string 对象
  • compare 成员函数可用于比较字符串。compare 成员函数有以下返回值:
    • 小于 0 表示当前的字符串小;
    • 等于 0 表示两个字符串相等;
    • 大于 0 表示另一个字符串小。
C++ 复制代码
string s1("hello"), s2("hello, world");
int n = s1.compare(s2);
n = s1.compare(1, 2, s2, 0, 3);  //比较s1的子串 (1,2) 和s2的子串 (0,3)
n = s1.compare(0, 2, s2);  // 比较s1的子串 (0,2) 和 s2
n = s1.compare("Hello");
n = s1.compare(1, 2, "Hello");  //比较 s1 的子串(1,2)和"Hello"
n = s1.compare(1, 2, "Hello", 1, 2);  //比较 s1 的子串(1,2)和 "Hello" 的子串(1,2)

2.6 查找字符串(字符)

  • string 类有一些查找子串和字符的成员函数,它们的返回值都是子串或字符在 string 对象字符串中的位置(即下标)。

  • 如果查不到,则返回 string::npos。string: :npos 是在 string 类中定义的一个静态常量。这些函数如下:

    • find:从前往后查找子串或字符出现的位置。
    • rfind:从后往前查找子串或字符出现的位置。
    • find_first_of:从前往后查找何处出现另一个字符串中包含的字符。
    • find_last_of:从后往前查找何处出现另一个字符串中包含的字符。
    • find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。
    • find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。
  • 所有的字符串查找方法重载了以下四种类型:pos表示开始查找的位置。n表示查找匹配的次数。返回值是整数索引。

    • string (1) size_t find (const string& str, size_t pos = 0) const noexcept;
    • c-string (2) size_t find (const char* s, size_t pos = 0) const;
    • buffer (3) size_t find (const char* s, size_t pos, size_type n) const;
    • character (4) size_t find (char c, size_t pos = 0) const noexcept;
C++ 复制代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s1("Source Code");
    int n;
    if ((n = s1.find('u')) != string::npos) //查找 u 出现的位置
        cout << "1) " << n << "," << s1.substr(n) << endl;
    //输出 l)2,urce Code
    if ((n = s1.find("Source", 3)) == string::npos)
        //从下标3开始查找"Source",找不到
        cout << "2) " << "Not Found" << endl;  //输出 2) Not Found
    if ((n = s1.find("Co")) != string::npos)
        //查找子串"Co"。能找到,返回"Co"的位置
        cout << "3) " << n << ", " << s1.substr(n) << endl;
    //输出 3) 7, Code
    if ((n = s1.find_first_of("ceo")) != string::npos)
        //查找第一次出现或 'c'、'e'或'o'的位置
        cout << "4) " << n << ", " << s1.substr(n) << endl;
    //输出 4) l, ource Code
    if ((n = s1.find_last_of('e')) != string::npos)
        //查找最后一个 'e' 的位置
        cout << "5) " << n << ", " << s1.substr(n) << endl;  //输出 5) 10, e
    if ((n = s1.find_first_not_of("eou", 1)) != string::npos)
        //从下标1开始查找第一次出现非 'e'、'o' 或 'u' 字符的位置
        cout << "6) " << n << ", " << s1.substr(n) << endl;
    //输出 6) 3, rce Code
    return 0;
}

2.7 字符串拼接

  • +和+=运算符对string 对象执行字符串的连接操作
  • append 成员函数,可以用来向字符串后面添加内容。append 成员函数返回对象自身的引用。
    • string& append (const string& str);
    • string& append (const string& str, size_t subpos, size_t sublen);
    • string& append (const char* s);
    • string& append (const char* s, size_t n);
    • string& append (size_t n, char c);
    • string& append (InputIterator first, InputIterator last);
C++ 复制代码
string s1("123"), s2("abc");
s1.append(s2);  // s1 = "123abc"
s1.append(s2, 1, 2);  // s1 = "123abcbc"
s1.append(3, 'K');  // s1 = "123abcbcKKK"
s1.append("ABCDE", 2, 3);  // s1 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3)

2.8 字符串剪切

  • substr 成员函数可以用于求子串 (n, m),原型如下。调用时,如果省略 m 或 m 超过了字符串的长度,则求出来的子串就是从下标 n 开始一直到字符串结束的部分。例如:
    • string substr (size_t pos = 0, size_t len = npos) const;
C++ 复制代码
string s1 = "this is ok";
string s2 = s1.substr(2, 4);  // s2 = "is i"
s2 = s1.substr(2);  // s2 = "is is ok"

2.9 字符串替换

  • replace 成员函数可以对 string 对象中的子串进行替换,返回值为对象自身的引用。
    • string (1) string& replace (size_t pos, size_t len, const string& str);
    • string& replace (const_iterator i1, const_iterator i2, const string& str);
    • substring (2) string& replace (size_t pos, size_t len, const string& str,
      size_t subpos, size_t sublen);
    • c-string (3) string& replace (size_t pos, size_t len, const char* s);
    • string& replace (const_iterator i1, const_iterator i2, const char* s);
    • buffer (4) string& replace (size_t pos, size_t len, const char* s, size_t n);
    • string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);
    • fill (5) string& replace (size_t pos, size_t len, size_t n, char c);
    • string& replace (const_iterator i1, const_iterator i2, size_t n, char c);
    • range (6) string& replace (const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);
    • initializer list (7) string& replace (const_iterator i1, const_iterator i2, initializer_list il);
C++ 复制代码
string s1("Real Steel");
s1.replace(1, 3, "123456", 2, 4);  //用 "123456" 的子串(2,4) 替换 s1 的子串(1,3)
cout << s1 << endl;  //输出 R3456 Steel
string s2("Harry Potter");
s2.replace(2, 3, 5, '0');  //用 5 个 '0' 替换子串(2,3)
cout << s2 << endl;  //输出 HaOOOOO Potter
int n = s2.find("OOOOO");  //查找子串 "00000" 的位置,n=2
s2.replace(n, 5, "XXX");  //将子串(n,5)替换为"XXX"
cout << s2 < < endl;  //输出 HaXXX Potter

2.10 字符串插入

  • insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。例如:

    • string& insert (size_t pos, const string& str);
    • string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
    • string& insert (size_t pos, const char* s);
    • string& insert (size_t pos, const char* s, size_t n);
    • string& insert (size_t pos, size_t n, char c);
    • void insert (iterator p, size_t n, char c);
    • iterator insert (iterator p, char c);
    • void insert (iterator p, InputIterator first, InputIterator last);
C++ 复制代码
string s1("Limitless"), s2("00");
s1.insert(2, "123");  //在下标 2 处插入字符串"123",s1 = "Li123mitless"
s1.insert(3, s2);  //在下标 2 处插入 s2 , s1 = "Li10023mitless"
s1.insert(3, 5, 'X');  //在下标 3 处插入 5 个 'X',s1 = "Li1XXXXX0023mitless"

2.11 字符串删除

  • erase 成员函数可以删除 string 对象中的子串,返回值为对象自身的引用。如果使用了迭代器。则返回值为指向删除序列后的第一个字符的迭代器。
    • sequence (1)string& erase (size_t pos = 0, size_t len = npos);
    • character (2)iterator erase (const_iterator p);
    • range (3)iterator erase (const_iterator first, const_iterator last);
C++ 复制代码
string s1("Real Steel");
s1.erase(1, 3);  //删除子串(1, 3),此后 s1 = "R Steel"
s1.erase(5);  //删除下标5及其后面的所有字符,此后 s1 = "R Ste"

3 字符串转换

3.1 数值转换

  • s表示字符串
  • p表示在转换过程中遇到的第一个转换不了的字符。p可以得到它的下标。
  • b表示转换的默认进制。默认是10进制
函数 说明
string string to_string(val) 一组重载函数。返回val值的string表示。
int stoi(string s,size_t*p,int b) 返回整形
long stol(s,p,b) 返回long
unsigned long stoul(s,p,b) 返回unsigned long
long long stoll(s,p,b) 返回longlong
unsigned long long stoull(s,p,b) 返回unsigned longlong
float stof(s,p) 返回float
double stod(s,p) 返回double
long double stold(s,p) 返回long double

3.2 C字符串转string

str ="helloworld";
string s(str);

3.3 string转C风格字符串

string s("helloworld");
const char * str = s.c_str();

4 字符串流对象

  • 将string视为特殊的字符串流。使用流对象的方法处理字符串。
  • 使用流对象 istringstream 和 ostringstream,可以将 string 对象当作一个流进行输入输出。使用这两个类需要包含头文件 sstream。
C++ 复制代码
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
    string src("Avatar 123 5.2 Titanic K");
    istringstream istrStream(src); //建立src到istrStream的联系
    string s1, s2;
    int n;  double d;  char c;
    istrStream >> s1 >> n >> d >> s2 >> c; //把src的内容当做输入流进行读取
    ostringstream ostrStream;
    ostrStream << s1 << endl << s2 << endl << n << endl << d << endl << c <<endl;
    cout << ostrStream.str();
    return 0;
}

5 正则匹配

在正则表达式部分,有专门针对string的正则匹配搜索算法。

6 C字符串

头文件

#include<cstring>
#include<cstdlib>
#include<cstdio>

方法

名称 函数 & 目的
strcpy(s1, s2); 复制字符串 s2 到字符串 s1。
strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。连接字符串也可以用 + 号,例如:string str1 = "runoob";string str2 = "google";string str = str1 + str2;
strlen(s1); 返回字符串 s1 的长度。
strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

7 字符串分割的两种处理方式

字符串流分割

  • 使用getline()有分隔符的读入。和istringstream方法。对字符串进行分割。
C++ 复制代码
getline(istream,string,delim)
C++ 复制代码
istringstream is(ss);
string temp;
while(getline(is,temp,' ')){
    // cout<<"a"<<temp<<"b"<<endl;
    if(temp=="")continue;
    st.push(temp);
}

字符串方法分割

  • 使用find(patter,pos)和substr(pos,length)两个函数进行查找和剪切。
C++ 复制代码
    string strs ="  adb   dai fei af";
    
    string pattern = " ";
    size_t start_pos=0;
    size_t end_pos = strs.find(pattern,start_pos);
    vector<string> vec;
    string temp;
    while (end_pos != string::npos)
    {   cout<<start_pos<<"--"<<end_pos<<endl;
        if(start_pos!=end_pos){
            temp = strs.substr(start_pos,end_pos-start_pos);
            vec.push_back(temp);
        }
        start_pos = end_pos+1;
        end_pos = strs.find(pattern,start_pos);
        
    }
    vec.push_back(strs.substr(start_pos,strs.size()-start_pos));
    for(auto a : vec){
        cout<<"name:"<<a<<":end"<<endl;
    }
    return 0;

8 字符串格式化的两种处理方式

C-sprintf格式化字符串

C++ 复制代码
#include <stdio.h>
using std::string;
// 准备数据
string haha("haha");
int num = 3;
// 准备格式
string fmt("test string: %s. test number: %d");
char targetString[1024];
// 格式化,并获取最终需要的字符串
int realLen = sprintf( targetString, 
						sizeof(targetString), 
						fmt.c_str(), 
						haha.c_str(), 
						num );

字符串流格式化

C++ 复制代码
使用stringstream格式化字符串
#include <sstream>
using std::stringstream;
// 准备数据
string haha("haha");
int num = 3;
// 准备根据格式造字符串流
stringstream fmt; //或者使用 ostringstream
// 造字符串流
fmt << "test string: " << haha << ". test number: " << num;
// 获取最终需要的字符串
string targetString = fmt.str();

9 字符串匹配match和查找search的多种实现方法

  • match整个字符串符合要求
  • search找到符合要求的字符串子串。

循环暴力查找

暴力

成员函数find查找

参考 字符串find

模板函数find查找

参考 算法

正则表达式匹配

见正则表达式

10 字符串替换的多重实现方法

暴力替换

    string replaceSpace1(string s) {
        string result;
        for(int i=0;i<s.size();i++){
            if(s[i]==' '){
                result.append("%20");
            }
            else{
                result.push_back(s[i]);
            }

        }
        return result;
    }

容器库的erase和insert替换

    // 使用字符串库STL容器库的方法试一下
    string replaceSpace2(string s) {
        auto beg = s.begin();
        auto end = s.end();
        while(beg<end){
            if(*beg==' '){
                beg = s.erase(beg);
                beg = s.insert(beg,{'%','2','0'});
                end = s.end();
            }
            else{
                beg++;
            }
        }
        return s;
    }

string对象的find和replace替换

    // 使用字符串库STL容器库的find和replace试一下
    string replaceSpace(string s) {
        int pos=0;
        string str="%20";
        pos=s.find(" ",pos);
        while(pos!=string::npos){
            s.replace(pos,1,str);
            pos=s.find(" ",pos);
        }
        return s;
    }
相关推荐
海绵波波1073 分钟前
Webserver(4.9)本地套接字的通信
c++
黑叶白树6 分钟前
简单的签到程序 python笔记
笔记·python
@小博的博客9 分钟前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
幸运超级加倍~44 分钟前
软件设计师-上午题-15 计算机网络(5分)
笔记·计算机网络
南宫生1 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
爱吃喵的鲤鱼1 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
懒惰才能让科技进步2 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
7年老菜鸡2 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Ni-Guvara2 小时前
函数对象笔记
c++·算法
love_and_hope2 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习