重复删除子字符串后,查找剩余的字符串
Find remaining string after deleting a substring repeately
令s和t作为字符串。然后,我们在s中首次出现t中从s中删除t,然后将其余的s串称为s1。同样,我们在S1中的第一次出现时从S1中删除t,并将其余的S1字符串称为S2。反复这样做,直到sk中没有子字符串t。
请注意,删除t后我们可能在s中具有一个子字符串t。剩余的s串是什么?(如果S为空,那很好。)
约束:
- 1< =长度(s)< = 10^6。
- 1< =长度(t)< = 100。
例如,s =" aa abba b abba bab",t =" abba"。其余的字符串为" ab"。
我正在考虑使用KMP在T上具有前缀。然后,当我们在s中找到字符串t时,我们必须将索引i和j(i和s for s,j for t)更改为新位置。但是,我不确定J(可能是我)应该是什么?字符串可能有很多片段。
我的方法正确吗?如果是这样,您能否给我详细的步骤,我该怎么做,尤其是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;
}
非常感谢。
我发现了代码。我需要2个阵列:
-
prev
:在S
上存储i
索引的先前位置。最初是prev[i] = prev[i - 1]
。当我们在i + length(T)
位置找到匹配时,我们将设置prev[i + length(T) + 1] = i - 1
(即我们指向新位置的prev
i
以跳过整个字符串T
)。 -
jv
:在S
上的每个i
位置存储j
的值。
删除S
中的所有T
后,我们使用prev
重建剩余的字符串。总体复杂性是O(n m)
。
这是整个代码:
std::string remaining_after_delete_repeatedly(std::string s, std::string t) {
std::vector<int> prefix = make_prefix(t);
s += "#";
std::vector<int> prev(s.length());
std::vector<int> jv(s.length());
for (int i = 0; i < s.length(); prev[i] = i - 1, ++i);
for (int i = 0, j = 0; i < s.length(); ) {
if (s[i] == t[j]) {
jv[i] = j;
++i;
++j;
}
else if (j > 0)
j = prefix[j - 1];
else
jv[i++] = 0;
if (j == (int)t.length()) {
int u = i - 1;
for (int k = 0; k < t.length(); ++k)
u = prev[u];
prev[i] = u;
j = u < 0 ? 0 : jv[u] + 1;
}
}
std::string answer(1, s.back());
for (int i = prev[s.length() - 1]; i > -1; i = prev[i])
answer += s[i];
std::reverse(answer.begin(), answer.end());
return answer.substr(0, answer.length() - 1);
}
相关文章:
- 使用正则表达式regex_search在字符串中查找字符串
- 按类型与字符串查找对象
- 使用C RTTI(内置)通过字符串查找功能指针
- 关于获取行和字符串查找函数的问题
- 字符串查找方法找不到第一字母
- C++ 字符串.查找()
- 遇到字符串::查找的问题
- 将一个数组作为子字符串查找到另一个数组中
- 字符串查找第一个非的 C++ 问题
- 如何将通配符与字符串::查找一起使用
- 字符串::查找问题 (C++)
- 性能标准::strstr vs. 标准::字符串::查找
- C++字符串::查找崩溃应用程序
- 使用字符串查找单词的正确方法是什么
- 如何在<string>没有 std::string 中介的情况下制作一个支持通过 C 字符串查找的集合?
- 使用C++根据行中的第一个字符串查找行(仅一个)
- Borland字符串::查找bug
- std::map如何通过字符串查找元素
- 字符串查找函数返回奇数
- 如何使用子字符串查找数字行的正确部分