📌  相关文章
📜  查找并替换给定字符串中所有出现的子字符串

📅  最后修改于: 2022-05-13 01:56:09.595000             🧑  作者: Mango

查找并替换给定字符串中所有出现的子字符串

给定三个字符串SS1S2 ,分别由NMK个字符组成,任务是通过将字符串S中的所有子字符串S1替换为字符串S2来修改字符串S

例子:

朴素方法:解决给定问题的最简单方法是遍历字符串S ,当在字符串S中找到任何字符串S1作为子字符串时,将其替换为S2 请按照以下步骤解决此问题:

  • 初始化一个字符串ans以在替换所有出现后存储结果字符串 字符串S中的子字符串S1S2
  • 使用变量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填充该向量。
  • 将两个变量ij初始化为0 ,分别存储当前字符在ss1中的位置。
  • 初始化一个向量,该向量用于存储S中出现字符串S1的所有起始索引。
  • 使用变量i遍历字符串S的字符并执行以下步骤:
    • 如果S[i]等于S1[j] ,则将ij1。
    • 如果j等于s1的长度,则将值(i – j)添加到找到的向量并将j更新为lps[j – 1]
    • 否则,如果S[i]的值不等于S1[j] ,那么如果j等于0 ,则将i的值增加1 。否则,将j更新为lps[j – 1]
  • 初始化一个变量,比如prev0来存储最后更改的索引,一个空字符串ans来存储替换所有初始值后的结果字符串 出场 s1s2s 中。
  • 遍历向量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)