模拟专题
字符串模拟
c++ 常用字符串处理函数
1. 截取子串
s.substr(pos, n) 截取s中从pos开始(包括0)的n个字符的子串,并返回
s.substr(pos) 截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
2. 替换子串
s.replace(pos, n, s1) 用s1替换s中从pos开始(包括0)的n个字符的子串
3. 查找子串
s.find(s1) 查找s中第一次出现s1的位置,并返回(包括0)
s.find(s1 , p) 从位置p开始查找s中第一次出现s1的位置,并返回(包括0)
s.rfind(s1) 查找s中最后次出现s1的位置,并返回(包括0)
s.find_first_of(s1) 查找在s1中任意一个字符在s中第一次出现的位置,并返回(包括0)
s.find_last_of(s1) 查找在s1中任意一个字符在s中最后一次出现的位置,并返回(包括0)
s.fin_first_not_of(s1) 查找s中第一个不属于s1中的字符的位置,并返回(包括0)
s.fin_last_not_of(s1) 查找s中最后一个不属于s1中的字符的位置,并返回(包括0)
4、删除字符串
iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串
5、判断与转换函数
isdigit
:判断是否是数字isalpha
:判断是否是字母tolower
:大写转化为小写
6 翻了(替换子串)
解题思路:这题是练习使用replace函数的 , 当我们使用该函数替换后,由于原字符的一些片段被替换后,会导致字符串的长度发生变化,因此我们在使用好,切记要与变化后的长度进行相应变化。
代码:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
string s;
getline(cin, s);
int n = s.size();
int p = 0;
cout << n << endl;
for (int i = 0 ; i < n ; ++i) {
if (s[i] == '6') {
p = i;
int ss = 0;
while (s[i] == '6')
ss++, i++;
cout << ss << " " << p << endl;
if (ss > 3 && ss <= 9) {
[添加链接描述](https://pintia.cn/problem-sets/994805046380707840/problems/1111914599412858880) s.replace(p, ss, "9");
i = i - ss + 1; // 在替换之后字符串长度变换那么i对应的位置就需要变化
} else if (ss > 9) {
s.replace(p, ss, "27");
i = i - ss + 2;
}
}
n = s.size();
}
cout << s << endl;
return 0;
}
敲笨钟(字符串查找+字符串替换)
解题思路:
- 对于找有押韵的句子,我们的目标是前后两句的结尾都有ong的句子。那么由于这题的句子格式是固定的,因此我们通过找
ong,
判断前一个是否有,ong.
则是后一个。 - 对于替换的位置,我们可以从后面开始数空格数,当空格数是第三个的时候的位置为所求,同时当前位置是空格的位置,如果我们直接替换的话,会将空格消去,因此正确位置应该往后加一。
代码:
#include <iostream>
#include <string>
using namespace std;
string s, ss = "qiao ben zhong.";
int main() {
int n ;
cin >> n;
getchar();
while (n--) {
getline(cin, s);
int flag = 0;
if (s.find("ong,") != string::npos)
flag ++;
if (s.find("ong.") != string::npos)
flag ++;
if (flag == 2) {
int pos = s.size() - 1;
while (pos--) {
if (s[pos] == ' ')
flag ++;
if (flag == 5)
break;
}
s.replace(pos + 1, s.size() - pos, ss );
cout << s << endl;
} else
cout << "Skipped\n" ;
}
return 0;
}
估值一亿的AI核心代码(替换+删除+查找)
解题思路:
这是一个综合性非常强的题目了。对于删除字符来说,我们要灵活运用:iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
它仅删除指定位置的一个字符。
- 去除首位空格的方法,我们只需要在首部或者尾部,进行删除,直到不是空格就可以了。
- 去除单词之间的多余空格和标点符号前的所有字符:对于两个单词间的,当我们匹配到一个空格之后,开始判断下一个是否是空格,如果是的话删除(循环) ,对于标点符号,由于是前面不能留空格,那么如果我们在进行上面删除多余空格的操作后,如果后边的字符如果不是数字和字母(就是标点符号)那么我们就可以删除当前位置的空格。
- 后面替换操作的注意事项:要注意的是 can you、could you 换成了 can I、could I 后,这里的 I 不能再换成 you 了,所以可以先换成其他字符比如 ‘A’ 。替换是要注意判断它们是不是一个独立的部分,也就是说如果它们包含在两个单词之中,那么它就不能被替换。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
// 判断是否是独立的部分
bool judge(string &s, int x, int l) {
if ((x == 0 || (!isdigit(s[x - 1]) && !isalpha(s[x - 1]))) && (x + l == s.length() || (!isdigit(s[x + l])
&& !isalpha(s[x + l]))))
return true;
else
return false;
}
int main() {
int T;
cin >> T;
getchar();
while (T--) {
string s;
getline(cin, s);
cout << s << endl;
while (s[0] == ' ')
s.erase(s.begin()); //去掉开头的空格
while (s[s.length() - 1] == ' ')
s.erase(s.end() - 1); //去掉结尾的空格
for (int i = 0; i < s.length(); i++) {
if (s[i] == ' ') {
while (s[i + 1] == ' ')
s.erase(s.begin() + i + 1); //去掉多余空格
if (!isdigit(s[i + 1]) && !isalpha(s[i + 1]))
s.erase(s.begin() + i); //去掉标点前的空格
}
}
for (int i = 0; i < s.length(); i++) {
if (s[i] != 'I')
s[i] = tolower(s[i]);
}
for (int i = 0;; i++) {
i = s.find("can you", i);
if (i == -1)
break;
if (judge(s, i, 7))
s.replace(i, 7, "A can");
}
for (int i = 0;; i++) {
i = s.find("could you", i);
if (i == -1)
break;
if (judge(s, i, 9))
s.replace(i, 9, "A could");
}
for (int i = 0;; i++) {
i = s.find("I", i);
if (i == -1)
break;
if