📜  使用Z算法从给定字符串删除所有出现的单词

📅  最后修改于: 2021-04-17 16:18:26             🧑  作者: Mango

鉴于两个字符串str的长度为N和长度M,任务是从字符串str去除字符串的所有出现。

例子:

天真的方法:解决此问题的最简单方法是遍历字符串str的字符。对于每个索引,检查是否可以找到一个子字符串,该子字符串的起始索引等于当前索引,并且该子字符串等于字符串word 。如果发现为真,则删除子字符串。最后,打印字符串。
时间复杂度: O(N 2 )
辅助空间: O(1)

基于STL的方法:使用replace()方法从字符串str中删除所有出现的字符串单词
时间复杂度: O(N 2 )
辅助空间: O(1)

高效方法:可以使用Z算法对上述方法进行优化。请按照以下步骤解决问题:

  • 初始化一个字符串,例如res ,通过从给定字符串str中删除单词来存储该字符串。
  • 初始化一个数组,例如Z [] ,以存储字符串的Z值。
  • 使用Z算法查找给定字符串str中所有出现的字符串单词
  • 最后,遍历数组Z []并检查z [i + length(word)+1]是否等于length(word) 。如果发现是真的,则更新i + = length(word)– 1
  • 否则,将当前字符附加到字符串res中

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to fill the Z-array for str
void getZarr(string str, int Z[])
{
    int n = str.length();
    int k;
 
    // L Stores start index of window
    // which matches with prefix of str
    int L = 0;
 
    // R Stores end index of window
    // which matches with prefix of str
    int R = 0;
 
    // Iterate over the characters of str
    for (int i = 1; i < n; ++i) {
 
        // If i is greater thn R
        if (i > R) {
 
            // Update L and R
            L = R = i;
 
            // If substring match with prefix
            while (R < n && str[R - L] == str[R]) {
 
                // Update R
                R++;
            }
 
            // Update Z[i]
            Z[i] = R - L;
 
            // Update R
            R--;
        }
        else {
 
            // Update k
            k = i - L;
 
            // if Z[k] is less than
            // remaining interval
            if (Z[k] < R - i + 1) {
 
                // Update Z[i]
                Z[i] = Z[k];
            }
 
            else {
 
                // Start from R and check manually
                L = i;
                while (R < n && str[R - L] == str[R]) {
 
                    // Update R
                    R++;
                }
 
                // Update Z[i]
                Z[i] = R - L;
 
                // Update R
                R--;
            }
        }
    }
}
 
// Function to remove all the occurrences
// of word from str
string goodStr(string str, string word)
{
    // Create concatenated string "P$T"
    string concat = word + "$" + str;
    int l = concat.length();
 
    // Store Z array of concat
    int Z[l];
 
    getZarr(concat, Z);
 
    // Stores string, str by removing all
    // the occurrences of word from str
    string res;
 
    // Stores length of word
    int pSize = word.size();
 
    // Traverse the array, Z[]
    for (int i = 0; i < l; ++i) {
 
        // if Z[i + pSize + 1] equal to
        // length of word
        if (i + pSize < l - 1 && Z[i + pSize + 1] == pSize) {
 
            // Update i
            i += pSize - 1;
        }
        else if (i < str.length()) {
            res += str[i];
        }
    }
    return res;
}
 
// Driver Code
int main()
{
    string str
        = "Z-kmalgorithmkmiskmkmkmhelpfulkminkmsearching";
    string word = "km";
 
    cout << goodStr(str, word);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG
{
 
  // Function to fill the Z-array for str
  static void getZarr(String str, int Z[])
  {
    int n = str.length();
    int k;
 
    // L Stores start index of window
    // which matches with prefix of str
    int L = 0;
 
    // R Stores end index of window
    // which matches with prefix of str
    int R = 0;
 
    // Iterate over the characters of str
    for (int i = 1; i < n; ++i)
    {
 
      // If i is greater thn R
      if (i > R)
      {
 
        // Update L and R
        L = R = i;
 
        // If subString match with prefix
        while (R < n && str.charAt(R - L) ==
               str.charAt(R))
        {
 
          // Update R
          R++;
        }
 
        // Update Z[i]
        Z[i] = R - L;
 
        // Update R
        R--;
      }
      else
      {
 
        // Update k
        k = i - L;
 
        // if Z[k] is less than
        // remaining interval
        if (Z[k] < R - i + 1)
        {
 
          // Update Z[i]
          Z[i] = Z[k];
        }
 
        else
        {
 
          // Start from R and check manually
          L = i;
          while (R < n && str.charAt(R - L) ==
                 str.charAt(R))
          {
 
            // Update R
            R++;
          }
 
          // Update Z[i]
          Z[i] = R - L;
 
          // Update R
          R--;
        }
      }
    }
  }
 
  // Function to remove all the occurrences
  // of word from str
  static String goodStr(String str, String word)
  {
    // Create concatenated String "P$T"
    String concat = word + "$" + str;
    int l = concat.length();
 
    // Store Z array of concat
    int []Z = new int[l];
 
    getZarr(concat, Z);
 
    // Stores String, str by removing all
    // the occurrences of word from str
    String res="";
 
    // Stores length of word
    int pSize = word.length();
 
    // Traverse the array, Z[]
    for (int i = 0; i < l; ++i) {
 
      // if Z[i + pSize + 1] equal to
      // length of word
      if (i + pSize < l - 1 && Z[i + pSize + 1] == pSize) {
 
        // Update i
        i += pSize - 1;
      }
      else if (i < str.length()) {
        res += str.charAt(i);
      }
    }
    return res;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    String str
      = "Z-kmalgorithmkmiskmkmkmhelpfulkminkmsearching";
    String word = "km";
 
    System.out.print(goodStr(str, word));
  }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 program for the above approach
 
# Function to fill the Z-array for str
def getZarr(st, Z):
    n = len(st)
    k = 0
 
    # L Stores start index of window
    # which matches with prefix of str
    L = 0
 
    # R Stores end index of window
    # which matches with prefix of str
    R = 0
 
    # Iterate over the characters of str
    for i in range(1, n):
 
        # If i is greater thn R
        if (i > R):
 
            # Update L and R
            L = R = i
 
            # If substring match with prefix
            while (R < n and st[R - L] == st[R]):
 
                # Update R
                R += 1
 
            # Update Z[i]
            Z[i] = R - L
 
            # Update R
            R -= 1
 
        else:
 
            # Update k
            k = i - L
 
            # if Z[k] is less than
            # remaining interval
            if (Z[k] < R - i + 1):
 
                # Update Z[i]
                Z[i] = Z[k]
 
            else:
 
                # Start from R and check manually
                L = i
                while (R < n and st[R - L] == st[R]):
 
                    # Update R
                    R += 1
 
                # Update Z[i]
                Z[i] = R - L
 
                # Update R
                R -= 1
 
# Function to remove all the occurrences
# of word from str
 
 
def goodStr(st, word):
 
    # Create concatenated string "P$T"
    concat = word + "$" + st
    l = len(concat)
 
    # Store Z array of concat
    Z = [0]*l
 
    getZarr(concat, Z)
 
    # Stores string, str by removing all
    # the occurrences of word from str
    res = ""
 
    # Stores length of word
    pSize = len(word)
 
    # Traverse the array, Z[]
    for i in range(l):
 
        # if Z[i + pSize + 1] equal to
        # length of word
        if (i + pSize < l - 1 and Z[i + pSize + 1] == pSize):
 
            # Update i
            i += pSize - 1
 
        elif (i < len(st)):
            res += st[i]
 
    return res
 
# Driver Code
if __name__ == "__main__":
 
    st = "Z-kmalgorithmkmiskmkmkmhelpfulkminkmsearching"
    word = "km"
 
    print(goodStr(st, word))
 
    # This code is contributed by chitranayal.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
  // Function to fill the Z-array for str
  static void getZarr(string str, int[] Z)
  {
    int n = str.Length;
    int k;
 
    // L Stores start index of window
    // which matches with prefix of str
    int L = 0;
 
    // R Stores end index of window
    // which matches with prefix of str
    int R = 0;
 
    // Iterate over the characters of str
    for (int i = 1; i < n; ++i)
    {
 
      // If i is greater thn R
      if (i > R)
      {
 
        // Update L and R
        L = R = i;
 
        // If subString match with prefix
        while (R < n && str[R - L] ==
               str[R])
        {
 
          // Update R
          R++;
        }
 
        // Update Z[i]
        Z[i] = R - L;
 
        // Update R
        R--;
      }
      else
      {
 
        // Update k
        k = i - L;
 
        // if Z[k] is less than
        // remaining interval
        if (Z[k] < R - i + 1)
        {
 
          // Update Z[i]
          Z[i] = Z[k];
        }
 
        else
        {
 
          // Start from R and check manually
          L = i;
          while (R < n && str[R - L] ==
                 str[R])
          {
 
            // Update R
            R++;
          }
 
          // Update Z[i]
          Z[i] = R - L;
 
          // Update R
          R--;
        }
      }
    }
  }
 
  // Function to remove all the occurrences
  // of word from str
  static string goodStr(string str, string word)
  {
     
    // Create concatenated String "P$T"
    string concat = word + "$" + str;
    int l = concat.Length;
 
    // Store Z array of concat
    int []Z = new int[l];
    getZarr(concat, Z);
 
    // Stores String, str by removing all
    // the occurrences of word from str
    string res="";
 
    // Stores length of word
    int pSize = word.Length;
 
    // Traverse the array, Z[]
    for (int i = 0; i < l; ++i) {
 
      // if Z[i + pSize + 1] equal to
      // length of word
      if (i + pSize < l - 1 && Z[i + pSize + 1] == pSize) {
 
        // Update i
        i += pSize - 1;
      }
      else if (i < str.Length) {
        res += str[i];
      }
    }
    return res;
  }
 
  // Driver Code
  static public void Main()
  {
    string str
      = "Z-kmalgorithmkmiskmkmkmhelpfulkminkmsearching";
    string word = "km";
 
    Console.WriteLine(goodStr(str, word));
  }
}
 
// This code is contributed by sanjoy_62.


输出:
Z-algorithmishelpfulinsearching

时间复杂度: O(N + M)
辅助空间: O(N)