📜  查找X后是否在Y中存在X

📅  最后修改于: 2021-04-23 16:12:19             🧑  作者: Mango

给定两个包含小写字母的字符串XY ,任务是检查字符串X是否作为其子字符串存在于Y中。

例子:

方法:可以使用两个指针技术解决此问题。

  • 计算字符串X的每个字符的频率计数,并将其存储在数组cnt_X []中
  • 现在,对于子字符串Y [i…(i + X.length()-1)] ,可以使用cnt []生成相同的频率数组。
  • 使用第2步中的数组,可以通过将cnt [Y [i] –’a ‘]1并增加cnt [Y [i + X.length( )] –’a’]之前1
  • 比较每个窗口的cnt []cnt_X [] 。如果两者相等,则找到匹配项。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
const int MAX = 26;
  
// Function that returns true if both
// the arrays have equal values
bool areEqual(int* a, int* b)
{
    // Test the equality
    for (int i = 0; i < MAX; i++)
        if (a[i] != b[i])
            return false;
    return true;
}
  
// Function that returns true if any permutation
// of X exists as a substring in Y
bool xExistsInY(string x, string y)
{
  
    // Base case
    if (x.size() > y.size())
        return false;
  
    // To store cumulative frequency
    int cnt_x[MAX] = { 0 };
    int cnt[MAX] = { 0 };
  
    // Finding the frequency of
    // characters in X
    for (int i = 0; i < x.size(); i++)
        cnt_x[x[i] - 'a']++;
  
    // Finding the frequency of characters
    // in Y upto the length of X
    for (int i = 0; i < x.size(); i++)
        cnt[y[i] - 'a']++;
  
    // Equality check
    if (areEqual(cnt_x, cnt))
        return true;
  
    // Two pointer approach to generate the
    // entire cumulative frequency
    for (int i = 1; i < y.size() - x.size() + 1; i++) {
  
        // Remove the first character of
        // the previous window
        cnt[y[i - 1] - 'a']--;
  
        // Add the last character of
        // the current window
        cnt[y[i + x.size() - 1] - 'a']++;
  
        // Equality check
        if (areEqual(cnt, cnt_x))
            return true;
    }
  
    return false;
}
  
// Driver code
int main()
{
    string x = "skege";
    string y = "geeksforgeeks";
  
    if (xExistsInY(x, y))
        cout << "Yes";
    else
        cout << "No";
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
static int MAX = 26;
  
// Function that returns true if both
// the arrays have equal values
static boolean areEqual(int []a, int []b)
{
    // Test the equality
    for (int i = 0; i < MAX; i++)
        if (a[i] != b[i])
            return false;
    return true;
}
  
// Function that returns true if 
// any permutation of X exists 
// as a subString in Y
static boolean xExistsInY(String x, String y)
{
  
    // Base case
    if (x.length() > y.length())
        return false;
  
    // To store cumulative frequency
    int []cnt_x = new int[MAX];
    int []cnt = new int[MAX];
  
    // Finding the frequency of
    // characters in X
    for (int i = 0; i < x.length(); i++)
        cnt_x[x.charAt(i) - 'a']++;
  
    // Finding the frequency of characters
    // in Y upto the length of X
    for (int i = 0; i < x.length(); i++)
        cnt[y.charAt(i) - 'a']++;
  
    // Equality check
    if (areEqual(cnt_x, cnt))
        return true;
  
    // Two pointer approach to generate the
    // entire cumulative frequency
    for (int i = 1; i < y.length() - 
                        x.length() + 1; i++) 
    {
  
        // Remove the first character of
        // the previous window
        cnt[y.charAt(i - 1) - 'a']--;
  
        // Add the last character of
        // the current window
        cnt[y.charAt(i + x.length() - 1) - 'a']++;
  
        // Equality check
        if (areEqual(cnt, cnt_x))
            return true;
    }
    return false;
}
  
// Driver code
public static void main(String[] args)
{
    String x = "skege";
    String y = "geeksforgeeks";
  
    if (xExistsInY(x, y))
        System.out.print("Yes");
    else
        System.out.print("No");
}
}
  
// This code contributed by PrinciRaj1992


Python3
# Python3 implementation of the approach
MAX = 26
  
# Function that returns true if both
# the arrays have equal values
def areEqual(a, b):
      
    # Test the equality
    for i in range(MAX):
        if (a[i] != b[i]):
            return False
    return True
  
# Function that returns true if any permutation
# of X exists as a sub in Y
def xExistsInY(x,y):
  
    # Base case
    if (len(x) > len(y)):
        return False
  
    # To store cumulative frequency
    cnt_x = [0] * MAX
    cnt = [0] * MAX
  
    # Finding the frequency of
    # characters in X
    for i in range(len(x)):
        cnt_x[ord(x[i]) - ord('a')] += 1;
  
    # Finding the frequency of characters
    # in Y upto the length of X
    for i in range(len(x)):
        cnt[ord(y[i]) - ord('a')] += 1
  
    # Equality check
    if (areEqual(cnt_x, cnt)):
        return True
  
    # Two pointer approach to generate the
    # entire cumulative frequency
    for i in range(1, len(y) - len(x) + 1):
  
        # Remove the first character of
        # the previous window
        cnt[ord(y[i - 1]) - ord('a')] -= 1
  
        # Add the last character of
        # the current window
        cnt[ord(y[i + len(x) - 1]) - ord('a')] += 1
  
        # Equality check
        if (areEqual(cnt, cnt_x)):
            return True
  
    return False
  
# Driver Code
if __name__ == '__main__':
    x = "skege"
    y = "geeksforgeeks"
  
    if (xExistsInY(x, y)):
        print("Yes")
    else:
        print("No")
  
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
  
class GFG
{
static int MAX = 26;
  
// Function that returns true if both
// the arrays have equal values
static bool areEqual(int []a, 
                     int []b)
{
    // Test the equality
    for (int i = 0; i < MAX; i++)
        if (a[i] != b[i])
            return false;
    return true;
}
  
// Function that returns true if 
// any permutation of X exists 
// as a subString in Y
static bool xExistsInY(String x, 
                       String y)
{
  
    // Base case
    if (x.Length > y.Length)
        return false;
  
    // To store cumulative frequency
    int []cnt_x = new int[MAX];
    int []cnt = new int[MAX];
  
    // Finding the frequency of
    // characters in X
    for (int i = 0; i < x.Length; i++)
        cnt_x[x[i] - 'a']++;
  
    // Finding the frequency of characters
    // in Y upto the length of X
    for (int i = 0; i < x.Length; i++)
        cnt[y[i] - 'a']++;
  
    // Equality check
    if (areEqual(cnt_x, cnt))
        return true;
  
    // Two pointer approach to generate the
    // entire cumulative frequency
    for (int i = 1; i < y.Length - 
                        x.Length + 1; i++) 
    {
  
        // Remove the first character of
        // the previous window
        cnt[y[i - 1] - 'a']--;
  
        // Add the last character of
        // the current window
        cnt[y[i + x.Length - 1] - 'a']++;
  
        // Equality check
        if (areEqual(cnt, cnt_x))
            return true;
    }
    return false;
}
  
// Driver code
public static void Main(String[] args)
{
    String x = "skege";
    String y = "geeksforgeeks";
  
    if (xExistsInY(x, y))
        Console.Write("Yes");
    else
        Console.Write("No");
}
}
  
// This code is contributed by PrinciRaj1992


输出:
Yes

时间复杂度: O(xLen + yLen),其中xLen和yLen分别是字符串X和Y的长度。