【C++】标准模板库(中)
符串题目在很多比赛中都是必考的一类题目,而其中的题目好多都涉及到字符串的增删改查,如果使用字符数组来存储时,大部分的时间都浪费在了写循环上面,而c++中的string库包含了我们所要用到的大部分操作,几个for循环往往只用一个库函数就可以解决。
如定义一个string类型的变量a,既可以之间使用cin和cout输出整个字符串,也可以使用a[i]来访问字符串中的每一个元素,也可以使用+-运算符进行字符串的拼接...
输入运算符>>默认会忽略空格,遇到空格就认为输入结束止,但<<则会带同空格一起输出
string b;
cin>>b;
cout<<b<<endl;
string a="Hello world!";
cout<<a<<endl;
return 0;
当输入为Hello world!时
输出为:
Hello
Hello world!
一、string类的构造函数
主要有下面这七个构造函数,着重需要掌握的为后两个,难度相对也不是太大,基本上看一遍就可以记住。
1.默认构造
string s1;
cout << "s1:" <<s1<<endl;
输出
s1:
在类定义时,如果没有赋初值,会调用自身默认的无参构造,输出的为空字符串。
2.初始为c风格字符串
string s2("I am the second");
cout << "s2:" << s2 << endl;
输出
s2:I am the second
这个也比较好理解,就是把引号内的字符串传入带参构造函数,之后将该字符串赋值给了该对象。
3.初始化为n个字符c
string s3(20, '$');
cout << "s3:" << s3 << endl;
输出
s3:$$$$$$$$$$$$$$$$$$$$
要记住这个的数字是前一个参数,这个构造方法不是经常使用。
并且这里的第二个参数只能是单个字符。
4.初始化为string对象str
string s4(s2);
cout << "s4:" << s4 << endl;
输出
s1:I am the second
这个和第二个相似,只不过第二个参数也是一个字符串,第二个参数也可以是字符数组。
5.初始化为s指向的前n个字符
char c[] = "0123456789";
string s5(c,5);//0->4
cout << "s5:" << s5 << endl;
点击查看代码
s5:01234
这里的第二个参数表示一共有多少个字符,而不是下标。
6.初始化位s指向的一段字符
将另一个字符中的一段用来初始化该字符的方法一共有下面这三种,其中,前两种的思路基本一致,就是将字符串的起始和终止的地址传进去,所用到的构造函数也是同一个。
char c2[]= "0123456789";
string s6(c2 + 1, c2 + 7);
cout << "s6:" << s6 << endl;
string temp ("0123456789");
string s6_again(&temp[0], &temp[9]);
cout << "s6_again:" << s6_again << endl;
string c4("0123456789");
string s7(temp, 0, 5);
cout << "s7:" << s7<< endl;
上面这三种方法任选一种记忆即可。
二、字符串的拼接
有了 string 类,我们可以使用+或+=运算符来直接拼接字符串,非常方便,再也不需要使用C语言中的 strcat()、strcpy()、malloc() 等函数来拼接字符串了,再也不用担心空间不够会溢出了。
用+来拼接字符串时,运算符的两边可以都是 string 字符串,也可以是一个 string 字符串和一个C风格的字符串,还可以是一个 string 字符串和一个字符数组,或者是一个 string 字符串和一个单独的字符。
string s1 = "first ";
string s2 = "second ";
char *s3 = "third ";
char s4[] = "fourth ";
char ch = '@';
上面这几种变量都可以直接使用+-号进行运算。
三、字符串的增删改查
1.插入字符串
insert() 函数可以在 string 字符串中指定的位置插入另一个字符串
string s1, s2, s3;
s1 = s2 = "1234567890";
s3 = "aaa";
s1.insert(5, s3);
s2.insert(5, "bbb");
s1 = 12345aaa67890
s2 = 12345bbb67890
insert(index,s)中的第一个参数为插入的下标,在找到的位置前面插入字符串s。
2.删除字符串
erase() 函数可以删除 string 中的一个子字符串。
erase(start,len)
start 表示要删除的子字符串的起始下标,len 表示要删除子字符串的长度。如果不指明 len 的话,那么直接删除从 pos 到字符串结束处的所有字符(此时 len = str.length - start)。
string s1, s2, s3;
s1 = s2 = s3 = "1234567890";
s2.erase(5);
s3.erase(5, 3);
s1=1234567890
s2=12345
S3=1234590
待删除字符串最多只能删除到字符串结尾。
3.提取子字符串
substr() 函数用于从 string 字符串中提取子字符串
substr(start,len);
pos 为要提取的子字符串的起始下标,len 为要提取的子字符串的长度。
string s1 = "first second third";
string s2;
s2 = s1.substr(6, 6);
cout<< s1 <<endl;
cout<< s2 <<endl;
输出:
first second third
second
4.字符串查找
1.find() 函数
find() 函数用于在 string 字符串中查找子字符串出现的位置,它其中的两种原型为:
find (const string& str, size_t pos = 0);
find (const char* s, size_t pos = 0);
第一个参数为待查找的子字符串,它可以是 string 字符串,也可以是C风格的字符串。第二个参数为开始查找的位置(下标);如果不指明,则从第0个字符开始查找。
string s1 = "first second third";
string s2 = "second";
int index = s1.find(s2,5);
if(index < s1.length())
cout<<"Found at index : "<< index <<endl;
else
cout<<"Not found"<<endl;
输出:
Found at index : 6
-
find() 函数最终返回的是子字符串第一次出现在字符串中的起始下标。
-
如果没有查找到子字符串,那么会返回 -1。
2.rfind()函数
rfind() 和 find() 很类似,同样是在字符串中查找子字符串,不同的是 find() 函数从第二个参数开始往后查找,而 rfind() 函数则最多查找到第二个参数处,如果到了第二个参数所指定的下标还没有找到子字符串,则返回 string::npos。
3.find_first_of() 函数
find_first_of() 函数用于查找子字符串和字符串共同具有的字符在字符串中首次出现的位置。
string a="abcdef";
string b="hef";
cout<<a.find_first_of(b);
输出:
4
该函数不经常使用,但不排除会出现一个题使用该函数会很大的减少代码量。
四、天梯赛(2023年):L1-6 剪切粘贴
原题链接:https://www.acwing.com/problem/content/5012/
#include<bits/stdc++.h>
using namespace std;
int main()
{
string a;
getline(cin,a);
int n;cin>>n;
for(int i=0;i<n;i++)
{
int a1,a2;
string s1,s2;
cin>>a1>>a2>>s1>>s2;
string in(a,a1-1,a2-a1+1);
a.erase(a1-1,a2-a1+1);
int index=a.find(s1+s2);
if(index!=-1)
a.insert(index+s1.size(),in);
else a+=in;
}
cout<<a<<endl;
}

浙公网安备 33010602011771号