📌  相关文章
📜  检查一个字符串是否是另一个字符串的加扰形式

📅  最后修改于: 2021-04-27 17:20:02             🧑  作者: Mango

给定两个长度相等的字符串S1S2 ,任务是确定S2是否为S1的加扰形式。
炒字符串:
给定字符串str ,我们可以通过将其递归划分为两个非空子字符串来将其表示为二叉树。
注意:加扰的字符串与Anagram不同
以下是str = “ coder”的一种可能表示形式:

coder
   /    \
  co    der
 / \    /  \
c   o  d   er
           / \
          e   r

要对字符串加扰,我们可以选择任何非叶子节点并交换其两个子节点。
假设我们选择节点“ co”并交换其两个子节点,它将产生一个加扰的字符串“ ocder”。

ocder
   /    \
  oc    der
 / \    /  \
o   c  d   er
           / \
          e   r

因此,“ocder”“编码器”的炒字符串。
同样,如果我们继续交换节点“ der”“ er ”的子代,则会产生加扰字符串“ ocred”

ocred
   /    \
  oc    red
 / \    /  \
o   c  re  d
       / \
      r   e

因此,“光学字符识别”“编码器”的炒字符串。
例子:

方法
为了解决这个问题,我们采用分而治之的方法。
给定两个长度相等的字符串(例如n + 1),S1 [0…n]和S2 [0…n]。如果S2是S1的加扰形式,则必须存在一个索引i,使得至少满足以下条件之一:

  • S2 [0…i]是S1 [0…i]的加扰字符串,而S2 [i + 1…n]是S1 [i + 1…n]的加扰字符串。
  • S2 [0…i]是S1 [ni…n]的加扰字符串,而S2 [i + 1…n]是S1 [0…ni-1]的加扰字符串。

注意:这里要考虑的优化步骤是事先检查两个字符串是否彼此相同。如果不是,则表明字符串包含不同的字符,并且不能相互加扰。
下面是上述方法的实现:

C++
// C++ Program to check if a
// given string is a scrambled
// form of another string
 
#include 
using namespace std;
 
bool isScramble(string S1, string S2)
{
    // Strings of non-equal length
    // cant' be scramble strings
    if (S1.length() != S2.length()) {
        return false;
    }
 
    int n = S1.length();
 
    // Empty strings are scramble strings
    if (n == 0) {
        return true;
    }
 
    // Equal strings are scramble strings
    if (S1 == S2) {
        return true;
    }
 
    // Check for the condition of anagram
    string copy_S1 = S1, copy_S2 = S2;
 
    sort(copy_S1.begin(), copy_S1.end());
    sort(copy_S2.begin(), copy_S2.end());
 
    if (copy_S1 != copy_S2) {
        return false;
    }
 
    for (int i = 1; i < n; i++) {
 
        // Check if S2[0...i] is a scrambled
        // string of S1[0...i] and if S2[i+1...n]
        // is a scrambled string of S1[i+1...n]
        if (isScramble(S1.substr(0, i), S2.substr(0, i))
            && isScramble(S1.substr(i, n - i),
                          S2.substr(i, n - i))) {
            return true;
        }
 
        // Check if S2[0...i] is a scrambled
        // string of S1[n-i...n] and S2[i+1...n]
        // is a scramble string of S1[0...n-i-1]
        if (isScramble(S1.substr(0, i),
                       S2.substr(n - i, i))
            && isScramble(S1.substr(i, n - i),
                          S2.substr(0, n - i))) {
            return true;
        }
    }
 
    // If none of the above
    // conditions are satisfied
    return false;
}
 
// Driver Code
int main()
{
    string S1 = "coder";
    string S2 = "ocred";
 
    if (isScramble(S1, S2)) {
        cout << "Yes";
    }
    else {
        cout << "No";
    }
 
    return 0;
}


Java
// Java program to check if a
// given string is a scrambled
// form of another string
import java.util.*;
 
class GFG{
     
static boolean isScramble(String S1,
                          String S2)
{
     
    // Strings of non-equal length
    // cant' be scramble strings
    if (S1.length() != S2.length())
    {
        return false;
    }
     
    int n = S1.length();
 
    // Empty strings are scramble strings
    if (n == 0)
    {
        return true;
    }
     
    // Equal strings are scramble strings
    if (S1.equals(S2))
    {
        return true;
    }
     
    // Converting string to
    // character array
    char[] tempArray1 = S1.toCharArray();
    char[] tempArray2 = S2.toCharArray();
     
    // Checking condition for Anagram
    Arrays.sort(tempArray1);
    Arrays.sort(tempArray2);
     
    String copy_S1 = new String(tempArray1);
    String copy_S2 = new String(tempArray2);
     
    if (!copy_S1.equals(copy_S2))
    {
        return false;
    }
         
    for(int i = 1; i < n; i++)
    {
         
        // Check if S2[0...i] is a scrambled
        // string of S1[0...i] and if S2[i+1...n]
        // is a scrambled string of S1[i+1...n]
        if (isScramble(S1.substring(0, i),
                       S2.substring(0, i)) &&
            isScramble(S1.substring(i, n),
                       S2.substring(i, n)))
        {
            return true;
        }
 
        // Check if S2[0...i] is a scrambled
        // string of S1[n-i...n] and S2[i+1...n]
        // is a scramble string of S1[0...n-i-1]
        if (isScramble(S1.substring(n - i, n),
                       S2.substring(0, i)) &&
            isScramble(S1.substring(0, n - i),
                       S2.substring(i, n)))
        {
            return true;
        }
    }
     
    // If none of the above
    // conditions are satisfied
    return false;
}
 
// Driver Code
public static void main(String[] args)
{
    String S1 = "coder";
    String S2 = "ocred";
     
    if (isScramble(S1, S2))
    {
        System.out.println("Yes");
    }
    else
    {
        System.out.println("No");
    }
}
}
 
// This code is contributed by dadi madhav


Python3
# Python3 program to check if a
# given string is a scrambled
# form of another string
def isScramble(S1: str, S2: str):
     
    # Strings of non-equal length
    # cant' be scramble strings
    if len(S1) != len(S2):
        return False
 
    n = len(S1)
 
    # Empty strings are scramble strings
    if not n:
        return True
 
    # Equal strings are scramble strings
    if S1 == S2:
        return True
 
    # Check for the condition of anagram
    if sorted(S1) != sorted(S2):
        return False
 
    for i in range(1, n):
         
        # Check if S2[0...i] is a scrambled
        # string of S1[0...i] and if S2[i+1...n]
        # is a scrambled string of S1[i+1...n]
        if (isScramble(S1[:i], S2[:i]) and
            isScramble(S1[i:], S2[i:])):
            return True
 
        # Check if S2[0...i] is a scrambled
        # string of S1[n-i...n] and S2[i+1...n]
        # is a scramble string of S1[0...n-i-1]
        if (isScramble(S1[-i:], S2[:i]) and
            isScramble(S1[:-i], S2[i:])):
            return True
 
    # If none of the above
    # conditions are satisfied
    return False
 
# Driver Code
if __name__ == "__main__":
     
    S1 = "coder"
    S2 = "ocred"
     
    if (isScramble(S1, S2)):
        print("Yes")
    else:
        print("No")
 
# This code is contributed by sgshah2


C#
// C# program to check if a
// given string is a scrambled
// form of another string
using System;
using System.Collections.Generic;
class GFG {
     
    static bool isScramble(string S1, string S2)
    {
           
        // Strings of non-equal length
        // cant' be scramble strings
        if (S1.Length != S2.Length) 
        {
            return false;
        }
           
        int n = S1.Length;
       
        // Empty strings are scramble strings
        if (n == 0) 
        {
            return true;
        }
           
        // Equal strings are scramble strings
        if (S1.Equals(S2))
        {
            return true;
        }
           
        // Converting string to 
        // character array
        char[] tempArray1 = S1.ToCharArray();
        char[] tempArray2 = S2.ToCharArray();
           
        // Checking condition for Anagram
        Array.Sort(tempArray1);
        Array.Sort(tempArray2);
           
        string copy_S1 = new string(tempArray1);
        string copy_S2 = new string(tempArray2);
           
        if (!copy_S1.Equals(copy_S2)) 
        {
            return false;
        }
               
        for(int i = 1; i < n; i++)
        {
               
            // Check if S2[0...i] is a scrambled
            // string of S1[0...i] and if S2[i+1...n]
            // is a scrambled string of S1[i+1...n]
            if (isScramble(S1.Substring(0, i), 
                           S2.Substring(0, i)) && 
                isScramble(S1.Substring(i, n - i),
                           S2.Substring(i, n - i)))
            {
                return true;
            }
       
            // Check if S2[0...i] is a scrambled
            // string of S1[n-i...n] and S2[i+1...n]
            // is a scramble string of S1[0...n-i-1]
            if (isScramble(S1.Substring(0, i),
                           S2.Substring(n - i, i)) && 
                isScramble(S1.Substring(i, n - i),
                           S2.Substring(0, n - i))) 
            {
                return true;
            }
        }
           
        // If none of the above
        // conditions are satisfied
        return false;
    }
   
  // Driver code
  static void Main()
  {
        string S1 = "coder";
        string S2 = "ocred";
           
        if (isScramble(S1, S2)) 
        {
            Console.WriteLine("Yes");
        }
        else
        {
            Console.WriteLine("No");
        }
  }
}
 
// This code is contributed by divyeshrabadiya07


输出:
Yes