查找并替换给定字符串中所有出现的子字符串
给定三个字符串S 、 S1和S2 ,分别由N 、 M和K个字符组成,任务是通过将字符串S中的所有子字符串S1替换为字符串S2来修改字符串S 。
例子:
Input: S = “abababa”, S1 = “aba”, S2 = “a”
Output: aba
Explanation:
Change the substrings S[0, 2] and S[4, 6](= S1) to the string S2(= “a”) modifies the string S to “aba”. Therefore, print “aba”.
Input: S = “geeksforgeeks”, S1 = “eek”, S2 = “ok”
Output: goksforgoks
朴素方法:解决给定问题的最简单方法是遍历字符串S ,当在字符串S中找到任何字符串S1作为子字符串时,将其替换为S2 。 请按照以下步骤解决此问题:
- 初始化一个字符串ans以在替换所有出现后存储结果字符串 字符串S中的子字符串S1到S2 。
- 使用变量i遍历字符串S的字符并执行以下步骤:
- 如果字符串S的前缀子字符串等于索引i中的S1 ,则将字符串S2添加到字符串ans中。
- 否则,将当前字符添加到字符串ans中。
- 完成上述步骤后,打印字符串ans作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to replace all the occurrences
// of the substring S1 to S2 in string S
void modifyString(string& s, string& s1,
string& s2)
{
// Stores the resultant string
string ans = "";
// Traverse the string s
for (int i = 0; i < s.length(); i++) {
int k = 0;
// If the first character of
// string s1 matches with the
// current character in string s
if (s[i] == s1[k]
&& i + s1.length()
<= s.length()) {
int j;
// If the complete string
// matches or not
for (j = i; j < i + s1.length(); j++) {
if (s[j] != s1[k]) {
break;
}
else {
k = k + 1;
}
}
// If complete string matches
// then replace it with the
// string s2
if (j == i + s1.length()) {
ans.append(s2);
i = j - 1;
}
// Otherwise
else {
ans.push_back(s[i]);
}
}
// Otherwise
else {
ans.push_back(s[i]);
}
}
// Print the resultant string
cout << ans;
}
// Driver Code
int main()
{
string S = "geeksforgeeks";
string S1 = "eek";
string S2 = "ok";
modifyString(S, S1, S2);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to replace all the occurrences
// of the subString S1 to S2 in String S
static void modifyString(String s, String s1, String s2)
{
// Stores the resultant String
String ans = "";
// Traverse the String s
for (int i = 0; i < s.length(); i++) {
int k = 0;
// If the first character of
// String s1 matches with the
// current character in String s
if (s.charAt(i) == s1.charAt(k)
&& i + s1.length() <= s.length()) {
int j;
// If the complete String
// matches or not
for (j = i; j < i + s1.length(); j++) {
if (s.charAt(j) != s1.charAt(k)) {
break;
}
else {
k = k + 1;
}
}
// If complete String matches
// then replace it with the
// String s2
if (j == i + s1.length()) {
ans += (s2);
i = j - 1;
}
// Otherwise
else {
ans += (s.charAt(i));
}
}
// Otherwise
else {
ans += (s.charAt(i));
}
}
// Print the resultant String
System.out.print(ans);
}
// Driver Code
public static void main(String[] args)
{
String S = "geeksforgeeks";
String S1 = "eek";
String S2 = "ok";
modifyString(S, S1, S2);
}
}
// This code is contributed by gauravrajput1
C#
// C# program for the above approach
using System;
public class GFG {
// Function to replace all the occurrences
// of the subString S1 to S2 in String S
static void modifyString(String s, String s1, String s2)
{
// Stores the resultant String
String ans = "";
// Traverse the String s
for (int i = 0; i < s.Length; i++) {
int k = 0;
// If the first character of
// String s1 matches with the
// current character in String s
if (s[i] == s1[k]
&& i + s1.Length <= s.Length) {
int j;
// If the complete String
// matches or not
for (j = i; j < i + s1.Length; j++) {
if (s[j] != s1[k]) {
break;
}
else {
k = k + 1;
}
}
// If complete String matches
// then replace it with the
// String s2
if (j == i + s1.Length) {
ans += (s2);
i = j - 1;
}
// Otherwise
else {
ans += (s[i]);
}
}
// Otherwise
else {
ans += (s[i]);
}
}
// Print the resultant String
Console.Write(ans);
}
// Driver Code
public static void Main(String[] args)
{
String S = "geeksforgeeks";
String S1 = "eek";
String S2 = "ok";
modifyString(S, S1, S2);
}
}
// This code is contributed by gauravrajput1
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the LPS array
// for the given string S1
vector computeLPS(string& s1)
{
// Stores the longest proper prefix
// and suffix for each character
// in the string s1
vector lps(s1.length());
int len = 0;
// Set lps value 0 for the first
// character of the string s1
lps[0] = 0;
int i = 1;
// Iterate to fill the lps vector
while (i < s1.length()) {
if (s1[i] == s1[len]) {
len = len + 1;
lps[i] = len;
i = i + 1;
}
else {
// If there is no longest
// proper prefix which is
// suffix, then set lps[i] = 0
if (len == 0) {
lps[i] = 0;
i = i + 1;
}
// Otherwise
else
len = lps[len - 1];
}
}
return lps;
}
// Function to replace all the occurrences
// of the substring S1 to S2 in string S
void modifyString(string& s, string& s1,
string& s2)
{
vector lps = computeLPS(s1);
int i = 0;
int j = 0;
// Stores all the starting index
// from character S1 occurs in S
vector found;
// Iterate to find all starting
// indexes and store all indices
// in a vector found
while (i < s.length()) {
if (s[i] == s1[j]) {
i = i + 1;
j = j + 1;
}
// The string s1 occurrence is
// found and store it in found[]
if (j == s1.length()) {
found.push_back(i - j);
j = lps[j - 1];
}
else if (i < s.length()
&& s1[j] != s[i]) {
if (j == 0)
i = i + 1;
else
j = lps[j - 1];
}
}
// Stores the resultant string
string ans = "";
int prev = 0;
// Traverse the vector found[]
for (int k = 0; k < found.size(); k++) {
if (found[k] < prev)
continue;
ans.append(s.substr(prev, found[k] - prev));
ans.append(s2);
prev = found[k] + s1.size();
}
ans.append(s.substr(prev,
s.length() - prev));
// Print the resultant string
cout << ans << endl;
}
// Driver Code
int main()
{
string S = "geeksforgeeks";
string S1 = "eek";
string S2 = "ok";
modifyString(S, S1, S2);
return 0;
}
输出:
goksforgoks
时间复杂度: O(N*M)
辅助空间: O(N)
Efficient Approach:上述方法也可以通过创建最长的 字符串S1的正确前缀和后缀数组,然后执行 KMP 算法以查找字符串S1在字符串S中的出现。请按照以下步骤解决此问题:
- 创建一个向量,例如lps[] ,它存储每个字符的最长正确前缀和后缀,并使用 KMP 算法为字符串S1填充该向量。
- 将两个变量i和j初始化为0 ,分别存储当前字符在s和s1中的位置。
- 初始化一个向量,该向量用于存储在S中出现字符串S1的所有起始索引。
- 使用变量i遍历字符串S的字符并执行以下步骤:
- 如果S[i]等于S1[j] ,则将i和j加1。
- 如果j等于s1的长度,则将值(i – j)添加到找到的向量并将j更新为lps[j – 1] 。
- 否则,如果S[i]的值不等于S1[j] ,那么如果j等于0 ,则将i的值增加1 。否则,将j更新为lps[j – 1] 。
- 初始化一个变量,比如prev为0来存储最后更改的索引,一个空字符串ans来存储替换所有初始值后的结果字符串 出场 s1乘s2在s 中。
- 遍历向量found[] ,如果found[i]的值大于prev ,则添加字符串S2代替ans中的S1 。
- 完成上述步骤后,打印字符串ans作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the LPS array
// for the given string S1
vector computeLPS(string& s1)
{
// Stores the longest proper prefix
// and suffix for each character
// in the string s1
vector lps(s1.length());
int len = 0;
// Set lps value 0 for the first
// character of the string s1
lps[0] = 0;
int i = 1;
// Iterate to fill the lps vector
while (i < s1.length()) {
if (s1[i] == s1[len]) {
len = len + 1;
lps[i] = len;
i = i + 1;
}
else {
// If there is no longest
// proper prefix which is
// suffix, then set lps[i] = 0
if (len == 0) {
lps[i] = 0;
i = i + 1;
}
// Otherwise
else
len = lps[len - 1];
}
}
return lps;
}
// Function to replace all the occurrences
// of the substring S1 to S2 in string S
void modifyString(string& s, string& s1,
string& s2)
{
vector lps = computeLPS(s1);
int i = 0;
int j = 0;
// Stores all the starting index
// from character S1 occurs in S
vector found;
// Iterate to find all starting
// indexes and store all indices
// in a vector found
while (i < s.length()) {
if (s[i] == s1[j]) {
i = i + 1;
j = j + 1;
}
// The string s1 occurrence is
// found and store it in found[]
if (j == s1.length()) {
found.push_back(i - j);
j = lps[j - 1];
}
else if (i < s.length()
&& s1[j] != s[i]) {
if (j == 0)
i = i + 1;
else
j = lps[j - 1];
}
}
// Stores the resultant string
string ans = "";
int prev = 0;
// Traverse the vector found[]
for (int k = 0; k < found.size(); k++) {
if (found[k] < prev)
continue;
ans.append(s.substr(prev, found[k] - prev));
ans.append(s2);
prev = found[k] + s1.size();
}
ans.append(s.substr(prev,
s.length() - prev));
// Print the resultant string
cout << ans << endl;
}
// Driver Code
int main()
{
string S = "geeksforgeeks";
string S1 = "eek";
string S2 = "ok";
modifyString(S, S1, S2);
return 0;
}
输出:
goksforgoks
时间复杂度: O(N + M)
辅助空间: O(N)