📌  相关文章
📜  检查给定的字符串是否是另一个字符串的改组子字符串

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

给定字符串str1str2 。任务是发现str1是否为str2的改组形式的子字符串。如果str1str2的改组形式的子字符串,则打印“ YES”,否则打印“ NO”。

例子

方法:
令n = str1的长度,m = str2的长度。

  • 如果n> m,则字符串str1永远不能是str2的子字符串。
  • 否则将字符串str1排序。
  • 遍历字符串str2
    1. 将长度为n的str2的所有字符放在另一个字符串str中
    2. 对字符串str进行排序,并比较strstr1
    3. 如果str = str1,则字符串str1是字符串str2的混排子字符串。
    4. 否则重复上述过程,直到str2的第一个索引为(i – n + 1> m)(因为在此索引之后,剩余字符串str2的长度将小于str1
    5. 如果在上述步骤中str不等于str1,则字符串str1永远不能是str2的子字符串。

下面是上述方法的实现:

C++
// C++ program to check if string
// str1 is substring of str2 or not.
#include 
using namespace std;
 
// Function two check string A
// is shuffled  substring of B
// or not
bool isShuffledSubstring(string A, string B)
{
    int n = A.length();
    int m = B.length();
 
    // Return false if length of
    // string A is greater than
    // length of string B
    if (n > m) {
        return false;
    }
    else {
 
        // Sort string A
        sort(A.begin(), A.end());
 
        // Traverse string B
        for (int i = 0; i < m; i++) {
 
            // Return false if (i+n-1 >= m)
            // doesn't satisfy
            if (i + n - 1 >= m)
                return false;
 
            // Intialise the new string
            string str = "";
 
            // Copy the characters of
            // string B in str till
            // length n
            for (int j = 0; j < n; j++)
                str.push_back(B[i + j]);
 
            // Sort the string str
            sort(str.begin(), str.end());
 
            // Return true if sorted
            // string of "str" & sorted
            // string of "A" are equal
            if (str == A)
                return true;
        }
    }
}
 
// Driver Code
int main()
{
    // Input str1 and str2
    string str1 = "geekforgeeks";
    string str2 = "ekegorfkeegsgeek";
 
    // Function return true if
    // str1 is shuffled substring
    // of str2
    bool a = isShuffledSubstring(str1, str2);
 
    // If str1 is substring of str2
    // print "YES" else print "NO"
    if (a)
        cout << "YES";
    else
        cout << "NO";
    cout << endl;
    return 0;
}


Java
// Java program to check if String
// str1 is subString of str2 or not.
import java.util.*;
 
class GFG
{
 
// Function two check String A
// is shuffled subString of B
// or not
static boolean isShuffledSubString(String A, String B)
{
    int n = A.length();
    int m = B.length();
 
    // Return false if length of
    // String A is greater than
    // length of String B
    if (n > m)
    {
        return false;
    }
    else
    {
 
        // Sort String A
        A = sort(A);
 
        // Traverse String B
        for (int i = 0; i < m; i++)
        {
 
            // Return false if (i + n - 1 >= m)
            // doesn't satisfy
            if (i + n - 1 >= m)
                return false;
 
            // Intialise the new String
            String str = "";
 
            // Copy the characters of
            // String B in str till
            // length n
            for (int j = 0; j < n; j++)
                str += B.charAt(i + j);
 
            // Sort the String str
            str = sort(str);
 
            // Return true if sorted
            // String of "str" & sorted
            // String of "A" are equal
            if (str.equals(A))
                return true;
        }
    }
    return false;
}
 
// Method to sort a string alphabetically
static String sort(String inputString)
{
    // convert input string to char array
    char tempArray[] = inputString.toCharArray();
     
    // sort tempArray
    Arrays.sort(tempArray);
     
    // return new sorted string
    return String.valueOf(tempArray);
}
 
// Driver Code
public static void main(String[] args)
{
    // Input str1 and str2
    String str1 = "geekforgeeks";
    String str2 = "ekegorfkeegsgeek";
 
    // Function return true if
    // str1 is shuffled subString
    // of str2
    boolean a = isShuffledSubString(str1, str2);
 
    // If str1 is subString of str2
    // print "YES" else print "NO"
    if (a)
        System.out.print("YES");
    else
        System.out.print("NO");
    System.out.println();
}
}
 
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to check if string
# str1 is subof str2 or not.
 
# Function two check A
# is shuffled subof B
# or not
def isShuffledSubstring(A, B):
    n = len(A)
    m = len(B)
 
    # Return false if length of
    # A is greater than
    # length of B
    if (n > m):
        return False
    else:
 
        # Sort A
        A = sorted(A)
 
        # Traverse B
        for i in range(m):
 
            # Return false if (i+n-1 >= m)
            # doesn't satisfy
            if (i + n - 1 >= m):
                return False
 
            # Intialise the new string
            Str = ""
 
            # Copy the characters of
            # B in str till
            # length n
            for j in range(n):
                Str += (B[i + j])
 
            # Sort the str
            Str = sorted(Str)
 
            # Return true if sorted
            # of "str" & sorted
            # of "A" are equal
            if (Str == A):
                return True
 
# Driver Code
if __name__ == '__main__':
     
    # Input str1 and str2
    Str1 = "geekforgeeks"
    Str2 = "ekegorfkeegsgeek"
 
    # Function return true if
    # str1 is shuffled substring
    # of str2
    a = isShuffledSubstring(Str1, Str2)
 
    # If str1 is subof str2
    # print "YES" else print "NO"
    if (a):
        print("YES")
    else:
        print("NO")
 
# This code is contributed by mohit kumar 29


C#
// C# program to check if String
// str1 is subString of str2 or not.
using System;
 
public class GFG
{
  
// Function two check String A
// is shuffled subString of B
// or not
static bool isShuffledSubString(String A, String B)
{
    int n = A.Length;
    int m = B.Length;
  
    // Return false if length of
    // String A is greater than
    // length of String B
    if (n > m)
    {
        return false;
    }
    else
    {
  
        // Sort String A
        A = sort(A);
  
        // Traverse String B
        for (int i = 0; i < m; i++)
        {
  
            // Return false if (i + n - 1 >= m)
            // doesn't satisfy
            if (i + n - 1 >= m)
                return false;
  
            // Intialise the new String
            String str = "";
  
            // Copy the characters of
            // String B in str till
            // length n
            for (int j = 0; j < n; j++)
                str += B[i + j];
  
            // Sort the String str
            str = sort(str);
  
            // Return true if sorted
            // String of "str" & sorted
            // String of "A" are equal
            if (str.Equals(A))
                return true;
        }
    }
    return false;
}
  
// Method to sort a string alphabetically
static String sort(String inputString)
{
    // convert input string to char array
    char []tempArray = inputString.ToCharArray();
      
    // sort tempArray
    Array.Sort(tempArray);
      
    // return new sorted string
    return String.Join("",tempArray);
}
  
// Driver Code
public static void Main(String[] args)
{
    // Input str1 and str2
    String str1 = "geekforgeeks";
    String str2 = "ekegorfkeegsgeek";
  
    // Function return true if
    // str1 is shuffled subString
    // of str2
    bool a = isShuffledSubString(str1, str2);
  
    // If str1 is subString of str2
    // print "YES" else print "NO"
    if (a)
        Console.Write("YES");
    else
        Console.Write("NO");
    Console.WriteLine();
}
}
 
// This code is contributed by PrinciRaj1992


C++
#include
#include
#define MAX 256
using namespace std;
 
// This function returns true if contents of arr1[] and arr2[]
// are same, otherwise false.
bool compare(char arr1[], char arr2[])
{
    for (int i=0; i


Java
import java.util.*;
 
class GFG{
 
// This function returns true if
// contents of arr1[] and arr2[]
// are same, otherwise false.
static boolean compare(int []arr1, int []arr2)
{
    for(int i = 0; i < 256; i++)
        if (arr1[i] != arr2[i])
            return false;
             
    return true;
}
 
// This function search for all
// permutations of pat[] in txt[]
static boolean search(String pat, String txt)
{
    int M = pat.length();
    int N = txt.length();
     
    // countP[]: Store count of all
    // characters of pattern
    // countTW[]: Store count of
    // current window of text
    int []countP = new int [256];
    int []countTW = new int [256];
    for(int i = 0; i < 256; i++)
    {
        countP[i] = 0;
        countTW[i] = 0;
    }
         
    for(int i = 0; i < M; i++)
    {
        (countP[pat.charAt(i)])++;
        (countTW[txt.charAt(i)])++;
    }
 
    // Traverse through remaining
    // characters of pattern
    for(int i = M; i < N; i++)
    {
         
        // Compare counts of current
        // window of text with
        // counts of pattern[]
        if (compare(countP, countTW))
            return true;
 
        // Add current character to
        // current window
        (countTW[txt.charAt(i)])++;
 
        // Remove the first character
        // of previous window
        countTW[txt.charAt(i - M)]--;
    }
 
    // Check for the last window in text
    if (compare(countP, countTW))
        return true;
        return false;
}
 
// Driver code
public static void main(String[] args)
{
    String txt = "BACDGABCDA";
    String pat = "ABCD";
     
    if (search(pat, txt))
        System.out.println("Yes");
    else
        System.out.println("NO");
}
}
 
// This code is contributed by Stream_Cipher


Python3
MAX = 256
 
# This function returns true if contents
# of arr1[] and arr2[] are same,
# otherwise false.
def compare(arr1, arr2):
     
    global MAX
 
    for i in range(MAX):
        if (arr1[i] != arr2[i]):
            return False
             
    return True
 
# This function search for all permutations
# of pat[] in txt[]
def search(pat, txt):
     
    M = len(pat)
    N = len(txt)
 
    # countP[]: Store count of all characters
    #           of pattern
    # countTW[]: Store count of current window
    #            of text
    countP = [0 for i in range(MAX)]
    countTW = [0 for i in range(MAX)]
 
    for i in range(M):
        countP[ord(pat[i])] += 1
        countTW[ord(txt[i])] += 1
 
    # Traverse through remaining
    # characters of pattern
    for i in range(M, N):
         
        # Compare counts of current window
        # of text with counts of pattern[]
        if (compare(countP, countTW)):
            return True
             
        # Add current character
        # to current window
        countTW[ord(txt[i])] += 1
 
        # Remove the first character
        # of previous window
        countTW[ord(txt[i - M])] -= 1
 
    # Check for the last window in text
    if(compare(countP, countTW)):
        return True
        return False
 
# Driver code
txt = "BACDGABCDA"
pat = "ABCD"
 
if (search(pat, txt)):
    print("Yes")
else:
    print("No")
 
# This code is contributed by avanitrachhadiya2155


C#
using System.Collections.Generic;
using System;
 
class GFG{
 
// This function returns true if
// contents of arr1[] and arr2[]
// are same, otherwise false.
static bool compare(int []arr1, int []arr2)
{
    for(int i = 0; i < 256; i++)
        if (arr1[i] != arr2[i])
            return false;
             
    return true;
}
 
// This function search for all
// permutations of pat[] in txt[]
static bool search(String pat, String txt)
{
    int M = pat.Length;
    int N = txt.Length;
 
    // countP[]: Store count of all
    // characters of pattern
    // countTW[]: Store count of
    // current window of text
    int []countP = new int [256];
    int []countTW = new int [256];
     
    for(int i = 0; i < 256; i++)
    {
        countP[i] = 0;
        countTW[i] = 0;
    }
         
    for(int i = 0; i < M; i++)
    {
        (countP[pat[i]])++;
        (countTW[txt[i]])++;
    }
 
    // Traverse through remaining
    // characters of pattern
    for(int i = M; i < N; i++)
    {
         
        // Compare counts of current
        // window of text with
        // counts of pattern[]
        if (compare(countP, countTW))
            return true;
 
        // Add current character to
        // current window
        (countTW[txt[i]])++;
 
        // Remove the first character
        // of previous window
        countTW[txt[i - M]]--;
    }
 
    // Check for the last window in text
    if (compare(countP, countTW))
        return true;
        return false;
}
 
// Driver code
public static void Main()
{
    string txt = "BACDGABCDA";
    string pat = "ABCD";
     
    if (search(pat, txt))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("NO");
}
}
 
// This code is contributed by Stream_Cipher


输出:
YES

时间复杂度: O(m * n * log(n)),其中n =字符串str1的长度,m =字符串str2的长度
辅助空间: O(n)

高效的解决方案:此问题是Anagram Search的简单版本。可以使用字符频率计数在线性时间内解决。
在字母大小固定的假设下,我们可以实现O(n)时间复杂度,因为在ASCII中最多可以有256个字符,所以这通常是正确的。这个想法是使用两个count数组:

1)第一个计数数组存储模式中字符的频率。
2)第二个计数数组在当前文本窗口中存储字符的频率。
需要注意的重要一点是,比较两个计数数组的时间复杂度为O(1),因为它们中的元素数量是固定的(与模式和文本大小无关)。以下是此算法的步骤。
1)将模式频率的计数存储在第一个计数数组countP []中。还将字符的频率计数存储在数组countTW []中的文本的第一个窗口中。
2)现在运行一个从i = M到N-1的循环。循环执行。
…..a)如果两个计数数组相同,那么我们发现一个事件。
…..b)countTW []中文本的当前字符的增量计数
…..c)countWT []中前一个窗口中第一个字符的递减计数
3)上面的循环未检查最后一个窗口,因此请显式检查它。

以下是上述算法的实现。

C++

#include
#include
#define MAX 256
using namespace std;
 
// This function returns true if contents of arr1[] and arr2[]
// are same, otherwise false.
bool compare(char arr1[], char arr2[])
{
    for (int i=0; i

Java

import java.util.*;
 
class GFG{
 
// This function returns true if
// contents of arr1[] and arr2[]
// are same, otherwise false.
static boolean compare(int []arr1, int []arr2)
{
    for(int i = 0; i < 256; i++)
        if (arr1[i] != arr2[i])
            return false;
             
    return true;
}
 
// This function search for all
// permutations of pat[] in txt[]
static boolean search(String pat, String txt)
{
    int M = pat.length();
    int N = txt.length();
     
    // countP[]: Store count of all
    // characters of pattern
    // countTW[]: Store count of
    // current window of text
    int []countP = new int [256];
    int []countTW = new int [256];
    for(int i = 0; i < 256; i++)
    {
        countP[i] = 0;
        countTW[i] = 0;
    }
         
    for(int i = 0; i < M; i++)
    {
        (countP[pat.charAt(i)])++;
        (countTW[txt.charAt(i)])++;
    }
 
    // Traverse through remaining
    // characters of pattern
    for(int i = M; i < N; i++)
    {
         
        // Compare counts of current
        // window of text with
        // counts of pattern[]
        if (compare(countP, countTW))
            return true;
 
        // Add current character to
        // current window
        (countTW[txt.charAt(i)])++;
 
        // Remove the first character
        // of previous window
        countTW[txt.charAt(i - M)]--;
    }
 
    // Check for the last window in text
    if (compare(countP, countTW))
        return true;
        return false;
}
 
// Driver code
public static void main(String[] args)
{
    String txt = "BACDGABCDA";
    String pat = "ABCD";
     
    if (search(pat, txt))
        System.out.println("Yes");
    else
        System.out.println("NO");
}
}
 
// This code is contributed by Stream_Cipher

Python3

MAX = 256
 
# This function returns true if contents
# of arr1[] and arr2[] are same,
# otherwise false.
def compare(arr1, arr2):
     
    global MAX
 
    for i in range(MAX):
        if (arr1[i] != arr2[i]):
            return False
             
    return True
 
# This function search for all permutations
# of pat[] in txt[]
def search(pat, txt):
     
    M = len(pat)
    N = len(txt)
 
    # countP[]: Store count of all characters
    #           of pattern
    # countTW[]: Store count of current window
    #            of text
    countP = [0 for i in range(MAX)]
    countTW = [0 for i in range(MAX)]
 
    for i in range(M):
        countP[ord(pat[i])] += 1
        countTW[ord(txt[i])] += 1
 
    # Traverse through remaining
    # characters of pattern
    for i in range(M, N):
         
        # Compare counts of current window
        # of text with counts of pattern[]
        if (compare(countP, countTW)):
            return True
             
        # Add current character
        # to current window
        countTW[ord(txt[i])] += 1
 
        # Remove the first character
        # of previous window
        countTW[ord(txt[i - M])] -= 1
 
    # Check for the last window in text
    if(compare(countP, countTW)):
        return True
        return False
 
# Driver code
txt = "BACDGABCDA"
pat = "ABCD"
 
if (search(pat, txt)):
    print("Yes")
else:
    print("No")
 
# This code is contributed by avanitrachhadiya2155

C#

using System.Collections.Generic;
using System;
 
class GFG{
 
// This function returns true if
// contents of arr1[] and arr2[]
// are same, otherwise false.
static bool compare(int []arr1, int []arr2)
{
    for(int i = 0; i < 256; i++)
        if (arr1[i] != arr2[i])
            return false;
             
    return true;
}
 
// This function search for all
// permutations of pat[] in txt[]
static bool search(String pat, String txt)
{
    int M = pat.Length;
    int N = txt.Length;
 
    // countP[]: Store count of all
    // characters of pattern
    // countTW[]: Store count of
    // current window of text
    int []countP = new int [256];
    int []countTW = new int [256];
     
    for(int i = 0; i < 256; i++)
    {
        countP[i] = 0;
        countTW[i] = 0;
    }
         
    for(int i = 0; i < M; i++)
    {
        (countP[pat[i]])++;
        (countTW[txt[i]])++;
    }
 
    // Traverse through remaining
    // characters of pattern
    for(int i = M; i < N; i++)
    {
         
        // Compare counts of current
        // window of text with
        // counts of pattern[]
        if (compare(countP, countTW))
            return true;
 
        // Add current character to
        // current window
        (countTW[txt[i]])++;
 
        // Remove the first character
        // of previous window
        countTW[txt[i - M]]--;
    }
 
    // Check for the last window in text
    if (compare(countP, countTW))
        return true;
        return false;
}
 
// Driver code
public static void Main()
{
    string txt = "BACDGABCDA";
    string pat = "ABCD";
     
    if (search(pat, txt))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("NO");
}
}
 
// This code is contributed by Stream_Cipher
输出:
Yes