【字符串】基本知识

介绍字符串的基本知识、string模板的使用

名词

  • 字符集:一个字符集Σ\Sigma 是一个建立了全序关系的集合,Σ\Sigma 中的任意两个不同的元素α\alphaβ\beta 都拥有确定的大小关系。字符集Σ\Sigma 中的元素称为字符。
  • 字符串:字符串SS​ 是将nn​ 个字符按一定顺序排列形成的序列,nn​ 为字符串的长度,记作S|S|​ ,用S[i]S[i]​ 表示第ii​ 个字符,此处ii​ 从00​ 还是11​ 开始计数需要提前约定。
  • 子串:原字符串连续的一部分,记作S[i...j],ijS[i...j], i\leq j​​,表示原字符串中从S[i]S[i]​​ 到S[j]S[j]​​ 这一段组成的新字符串。有时也会用S[i..j],i>jS[i..j], i>j​​ , 来表示空串。
  • 子序列:从原字符串中将若干元素提取出来并不改变相对位置形成的序列,即S[p1],S[p2],...,S[pk],1p1<p2<<pkSS[p_1], S[p_2],...,S[p_k], 1\leq p_1<p_2<\dots<p_k\leq |S|​ 。
  • 前缀:指从串首开始到某个位置ii​ 结束的一个特殊子串。字符串SS 的以ii 结尾的前缀记为Preffix(S,i)Preffix(S,i)​ 。
  • 后缀:指从某个位置ii​ 开始到串尾结束的一个特殊子串。字符串SS​ 的从ii​ 开头的后缀记为Suffix(S,i)Suffix(S,i)。​​
  • 真前缀、真后缀:类比集合中真子集与子集的关系,即除去原字符串本身的所有前缀子串、后缀子串。
  • 字典序:以第ii 个字符作为第ii 关键字进行大小比较,空字符小于字符集内任何字符(即a<aaa<aa )。
  • 回文串:正着写和倒着写相同的字符串,即满足1iS,S[i]=S[S+1i]\forall 1\leq i\leq |S|, S[i]=S[|S|+1-i]​​的SS​ (ii 从0开始编号)。

来源:https://oi-wiki.org/string/basic/

char、C 风格字符串

string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//声明
string();
string (const string& str);
string (const string& str, size_t pos, size_t len = npos); //从str中pos位置截取len长度
string (const char* s); //C风格字符串
string (const char* s, size_t n); //C风格字符串截取前n个字符
string (size_t n, char c); //n个字符c
string (begin, end); //begin和end是迭代器,截取[begin, end)部分字符

//迭代器,可以用迭代器遍历字符串
str.begin(); str.end(); //获得首、尾迭代器
str.rbegin(); str.rend(); //获得反向首位迭代器

//空间
str.empty(); //为空返回1,不空返回0
str.size(); str.length(); //返回字符串实际长度
str.max_size(); //返回字符串最大容量
str.capacity(); //已分配内存中最多容纳字符个数
str.resize(x); //将字符串长度置为x
str.empty(); //清空字符串

//访问及修改
str[i]; str.at(i); //第i位(起始是第0位)
str.front(); str.back(); //字符串首位/末位
str += str1; str += "abc"; str += 'str'; //用+将字符/字符串添加到str末尾
str.append(...); //省略部分内容同string的构造,将其添加到str末尾
str.assign(...); //省略部分内容同string的构造,将str重置为省略部分所代表的内容
str.push_back(c); str.pop_back(); //向字符串末尾添加字符c/删除末尾字符
str.insert(pos, str1); //向str的pos下标前的位置插入字符串str1
str.insert(pos, str1, pos1, len); //向str的pos下标前的位置插入字符串str1从pos1位置截取len个字符
str.insert(pos, s); str.insert (pos, s, n); //s是字符指针
str.insert(pos, n, c); //向pos位置前插入n个字符c,此处的pos可以是下标或迭代器
str.insert(pos, begin, end); //pos、begin、end均为迭代器

str.erase(pos, len); //删除pos下标起的len个字符
str.erase(pos); str.erase(pos, begin, end); //这里均为迭代器,删除指向位置或左闭右开区间的字符
str.replace(pos, len, s); //pos起的len个字符,可替代成两个迭代器;s是string或字符指针,格式与上述其他方法基本相同

//一些方法
//< > >= <= == !=: 可以直接以字典序比较字符串
str.c_str(); //返回字符指针,即将string转换成C风格字符串
str.find(s); //s是string或字符指针或字符串常量,返回str里找到这个字符串的第一个下标,没有找到返回string::npos
str.rfind(s); //同find,不过查找顺序从后往前
str.substr(pos1, len); //返回pos1下标起的len个字符组成的子串,len省略则为pos1下标到结尾的子串
atoi(str); stoi(str); //字符串转int,返回数值。stoi会检查溢出,atoi不检查,溢出就输出最大值/最小值
//stol, stoll, stoull, stof, stod, stold同理

读入:

1
2
3
cin>>str; //遇空格/换行终止
getline(cin, str); //读取一行,包含空格
cin.getline(s, n); //s是字符指针,读取n个字符到s指向的字符数组中

stringstream

字符串流,实现其他类型的字符串格式化

头文件:

比C 风格的sprintf、sscanf安全

1
2
3
4
5
6
7
8
stringstream ss1;
stringstream ss(str); //将字符串str装入字符串流ss
ss << x; //将x装入输入流,x可以是任意类型
ss >> str; //取出ss流的开头写入str,返回bool类型,表示是否成功写入

//清空:进行多次不同类型转换之前必须清空字符串流
ss.clear(); //不释放内存
ss.str(""); //释放内存