【发布时间】:2017-03-15 18:47:49
【问题描述】:
让 S 和 T 被赋予字符串。然后我们在 S 中第一次出现 T 时从 S 中删除 T,并将 S 的剩余字符串称为 S1。同样,我们在 S1 中第一次出现 T 时从 S1 中删除 T,并将 S1 的剩余字符串称为 S2。重复这样做,直到在 Sk 中没有子字符串 T。
请注意,在删除 T 之后,我们可能在 S 中有一个子字符串 T。S 的剩余字符串是什么? (如果 S 为空也可以。)
约束:
- 1
- 1
例如,S = "aaabbababbabab",T = "abba"。剩下的字符串是“ab”。
我正在考虑使用 KMP 在 T 上添加前缀。然后当我们在 S 中找到字符串 T 时,我们必须将索引 i 和 j(i 代表 S,j 代表 T)更改为新位置。但是,我不确定 j(可能还有 i)应该是什么?字符串可能有很多片段。
我的方法正确吗?如果是这样,您能否给我详细的步骤,尤其是 j 的新值是多少?我坚持 j 的值。我不知道找到匹配项后应该将 j 分配给什么。这是我无法弄清楚的算法的一部分。
这是我未完成的代码。
std::vector<int> make_prefix(std::string &t) {
std::vector<int> prefix(t.length());
prefix[0] = 0;
for (int i = 1, j = 0; i < t.length(); )
if (t[i] == t[j]) {
prefix[i] = j + 1;
++i; ++j;
}
else if (j > 0)
j = prefix[j - 1];
else
prefix[i++] = 0;
return prefix;
}
std::string repeatRemoving(std::string s, std::string t) {
std::vector<int> prefix = make_prefix(t);
for (int i = 0, j = 0; i < s.length(); ) {
if (s[i] == t[j]) {
++i;
++j;
}
else if (j > 0)
j = prefix[j - 1];
else
++i;
if (j == (int)t.length()) {
// What should go here after finding a match?
// How can I adjust the values of i and j?
// How can I mark the deleted characters in s?
}
}
return s;
}
非常感谢。
【问题讨论】:
-
就像回顾 KMP 后的仓促猜测一样,我认为关键是记住之前部分匹配的开始和长度,直到可以通过找到不属于任何正在进行的匹配的字符来消除它们.
-
你不能使用
regex_replace()删除所有这些吗? -
它们可能重叠,S = "abababccc", T="abc" -> "ababcc",一次替换不正确
-
@KennyOstrom 正是我的想法。但是,我在实施时遇到了麻烦。它似乎比我想象的要复杂。 T 可以分成许多部分。
-
@Barmar 正如 Kenny Ostrom 所说,删除 T 后可能会形成一个新字符串 T。
标签: c++ arrays string algorithm search