L1-094 剪切粘贴 - 团体程序设计天梯赛-练习集 (pintia.cn)
题目具体要求👆
案例解析:
1.输入一份字符串
2.输入位置(2个整数) 然后把它们插入到 (主字符串的2个子字符串之间)
3.循环加工X次
需要解决的问题:
1.如何提取主字符串中的子字符串后再获得失去子字符串后的主字符串 即:
输入案例 3 5 7 8
主字符串:“12345678”
输入的 3 5 即 从第三个数到第五个数 也就是 ”345”这个子字符串 留着备用
现在主字符串是“12678” , 请看末尾的“78” 即 我们需要从中插入的位置 那么
插入后的结果就是 “12673458” ,加入空格后更加直观:“1267 345 8”。
2.题目要求的是寻找最近的位置点插入 所以:
假设主字符串是 “1234567878” 输入 3 5 7 8;
我们会发现主字符串中出现两组“78” 这里提供两种思路
1.通过Find方法先寻找7而后匹配8 即7后面是不是8 通过while 和break ,前者来控制寻找所有的7来匹配它们后面是否为8,break则在第一次寻找成功且匹配成功后退出循环.
2.通过合成字符串 即 7 8 合成为“78” 通过Find方法去寻找合适子字符串,而后通过Find方法返回的位置加上案例中7的长度 即1 而后插入剪切段后组合字符串即可.
注意点(2):
1.分割字符串我们可以使用到substr方法(用法百度)
2.注意如果没有找到合适字符串,我们就要把剪切内容加入到末尾,所以我们需要一个Bool来决定是否需要这么做.
代码如下: 用的是思路1
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main() {
string s;int a;
getline(cin, s);
cin >> a;
while (a--) {
int b, c;
string e, f;
cin >> b >> c >> e >> f;
string temp_s = ""; //临时字符串初始化
temp_s = s.substr(b-1 , c-(b-1) ); // 获得剪切段(题目中提到“位置总是合法的”)
string temp = ""; //初始化字符串temp
temp += s.substr(0, b-1); temp += s.substr(b - 1 + temp_s.length(), s.length() - (b - 1 + temp_s.length()));//获取剪切段以外的字符串组合成新的主字符串
s = temp; // 剪切后的字符串
bool t = false; // 默认未找到插入位置
size_t pos = 0; //Find中它被用作返回的位置
while ((pos = s.find(e, pos)) != std::string::npos) { // 这里用于寻找所以符合一层条件的项
if (pos != string::npos) { // 找到了
if (pos <= s.length() - (e.length() + f.length())) { //在合理范围内
if (f == s.substr(pos + e.length(), f.length())) {
string temp_q;
temp_q += s.substr(0, pos + e.length()); temp_q += temp_s; temp_q += s.substr(pos + e.length(), s.length() - (pos + e.length()));// 组合字符串
s = temp_q; t = true; // 完成剪 粘操作.
break; //操作完成后直接跳出循环
}
}
}
++pos; //迭代位置 继续寻找所用
}
if (t == false) s += temp_s; // 没找到 把剪切内容加入到末尾
}
cout << s << endl; //输出结果
return 0;
}
代码中很多地方可以优化,只是方法我没有去用,因为我喜欢拼积木的感觉,如果你想优化可以参考下面:
字符串可以使用erase方法用于删除剪切位置的内容这样合并等会显得十分简单,查找方面Find方法其实还有很多衍生的方法都是合适的.