剪切粘贴
前言
下面这题我写的时候一个点超时了,主要是在字符串查找的时候直接用了find
,实际上手搓一个o(n)的查找就能过,感觉挺有意思,特此记录。
题目
使用计算机进行文本编辑时常见的功能是剪切功能(快捷键:Ctrl + X)。请实现一个简单的具有剪切和粘贴功能的文本编辑工具。
工具需要完成一系列剪切后粘贴的操作,每次操作分为两步:
- 剪切:给定需操作的起始位置和结束位置,将当前字符串中起始位置到结束位置部分的字符串放入剪贴板中,并删除当前字符串对应位置的内容。例如,当前字符串为
abcdefg
,起始位置为 3,结束位置为 5,则剪贴操作后, 剪贴板内容为 cde
,操作后字符串变为 abfg
。字符串位置从 1 开始编号。
- 粘贴:给定插入位置的前后字符串,寻找到插入位置,将剪贴板内容插入到位置中,并清除剪贴板内容。例如,对于上面操作后的结果,给定插入位置前为
bf
,插入位置后为 g
,则插入后变为 abfcdeg
。如找不到应该插入的位置,则直接将插入位置设置为字符串最后,仍然完成插入操作。查找字符串时区分大小写。
每次操作后的字符串即为新的当前字符串。在若干次操作后,请给出最后的编辑结果。
输入格式:
输入第一行是一个长度小于等于 200 的字符串 S,表示原始字符串。字符串只包含所有可见 ASCII 字符,不包含回车与空格。
第二行是一个正整数 N (1≤N≤100),表示要进行的操作次数。
接下来的 N 行,每行是两个数字和两个长度不大于 5 的不包含空格的非空字符串,前两个数字表示需要剪切的位置,后两个字符串表示插入位置前和后的字符串,用一个空格隔开。如果有多个可插入的位置,选择最靠近当前操作字符串开头的一个。
剪切的位置保证总是合法的。
输出格式:
输出一行,表示操作后的字符串。
输入样例:
1 2 3 4 5 6 7
| AcrosstheGreatWall,wecanreacheverycornerintheworld 5 10 18 ery cor 32 40 , we 1 6 tW all 14 18 rnerr eache 1 1 e r
|
输出样例:
1
| he,allcornetrrwecaneacheveryGreatWintheworldAcross
|
题目引用自团体程序设计天梯赛真题(2023年)。
代码实现
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <bits/stdc++.h> using namespace std;
string textEditor(string originalString, const vector<vector<string>>& operations) { string currentString = originalString; string clipboard = ""; for (const auto& op : operations) { int start = stoi(op[0]); int end = stoi(op[1]); string before = op[2]; string after = op[3]; if (start < 1) start = 1; if (end > currentString.length()) end = currentString.length(); clipboard = currentString.substr(start - 1, end - (start - 1)); currentString = currentString.substr(0, start - 1) + currentString.substr(end); size_t insertPos = string::npos; if (before.empty() && after.empty()) { insertPos = currentString.length(); } else { for (size_t i = 0; i + before.length() + after.length() <= currentString.length(); ++i) { if (i + before.length() <= currentString.length() && currentString.substr(i, before.length()) == before) { if (i + before.length() + after.length() <= currentString.length() && currentString.substr(i + before.length(), after.length()) == after) { insertPos = i + before.length(); break; } } } } if (insertPos == string::npos) { currentString += clipboard; } else { currentString.insert(insertPos, clipboard); } clipboard = ""; } return currentString; }
int main() { string originalString; cin >> originalString; int n; cin >> n; vector<vector<string>> operations(n, vector<string>(4)); for (int i = 0; i < n; ++i) { cin >> operations[i][0] >> operations[i][1] >> operations[i][2] >> operations[i][3]; } string result = textEditor(originalString, operations); cout << result << endl; return 0; }
|
别问为什么一股AI味,因为就是AI写的哈哈哈,自己的题解打完比赛丢了,懒得自己再写一遍了。
解析
看代码就能知道,他这个字符串查找的办法就是直接一个for循环,一个个位置的判断(先判断前,然后判断后,这个方法挺巧的),时间复杂度只有o(n),还是不错滴。我当时的思路就是双指针一下,先find一个begin,再find一个end,但是其实这样就是o(n^2)了,寄!!!
总结
QwQ