题目传送门
思路
- 字符串处理
- 注意替换词可能再次被替换从而造成错误
- 注意删除字符之后,要控制指向字符串的指针
#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N = 1e5 + 10, M = N * 2;
const int INF = 0x3f3f3f3f3f3f3f3f;
// 判断是不是字母或者数字
bool is_word(char c)
{
if(isdigit(c)) return 1;
if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
return 1;
return 0;
}
// 循环替换某个独立的字符串
void s_replace(string& s, string& aim, string& s_ti)
{
int pos = 0;
while(s.find(aim, pos) != -1)
{
pos = s.find(aim, pos);
// 判断是不是独立的, 独立的才可以替换
if((pos == 0 || !is_word(s[pos - 1]))
&& (pos + aim.size() == s.size() || !is_word(s[pos + aim.size()])))
{
s.replace(pos, aim.size(), s_ti);
pos += s_ti.size();
}
else pos ++;
}
}
signed main()
{
int n;
cin >> n;
getchar();
while(n --)
{
string s;
getline(cin, s);
cout << s << endl;
// 1. 消除不合理的空格
for(int i = 0; i < s.size(); i ++)
{
if(s[i] == ' ')
{
// 第一个空格或者最后一个空格直接删除
if(i == 0 || i == s.size() - 1)
{
s.erase(i, 1);
i --;
}
// 只有空格右边是字母或者数字的左边不是空格的时候才是合法空格
else if(!(is_word(s[i - 1]) != ' ' && is_word(s[i + 1])))
{
s.erase(i, 1);
i --;
}
}
}
// 2. 大写变小写 and ?->!
for(int i = 0; i < s.size(); i ++)
{
if(s[i] >= 'A' && s[i] <= 'Z' && s[i] !='I')
{
s[i] = s[i] - 'A' + 'a';
}
if(s[i] == '?') s[i] = '!';
}
// 3. 替换独立的I和me为 you
string aim1 = "I", aim2 = "me";
string s_ti = "YOU";
int pos = 0;
s_replace(s, aim1, s_ti);
s_replace(s, aim2, s_ti);
// 4. 把原文中所有独立的 can you、could you 对应地换成 I can、I could
string aim3 = "can you", aim4 = "could you";
string s_ti3 = "I can", s_ti4 = "I could";
s_replace(s, aim3, s_ti3);
s_replace(s, aim4, s_ti4);
// 最后将假的替换词(YOU)替换为为真的替换词(you)
pos = 0;
while(s.find(s_ti,pos) != -1)
{
pos = s.find(s_ti, pos);
s.replace(pos, s_ti.size(), "you");
pos += 3;
}
cout << "AI: " << s << endl;
}
return 0;
}