📌  相关文章
📜  检查在给定的约束下是否有可能从A形成字符串B

📅  最后修改于: 2021-04-23 21:57:57             🧑  作者: Mango

给定两个字符串AB以及两个整数bm 。的任务是发现,如果有可能从A这样形成字符串BA被分成的B字符组除了这将有字符≤b中的最后一组,你被允许从每个组挑atmost字符,和并且B中的字符顺序必须与A相同。如果可能,则打印“是”,否则打印“否”

例子:

方法:想法是使用二进制搜索。通过迭代字符串A和存储每个A的向量S的字符的频率。现在遍历B ,如果当前字符不在矢量中,则打印No,因为它不可能使用A形成字符串B。否则,检查当前字符的第一次出现从最后选择的字符的索引,其表示从那里我们要匹配字符串B的字符开始字符串位置开始。跟踪存储在每个组中的字符数。如果超过,字符在当前块的给定的限制,我们更新了指针到下一个块。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function that returns true if it is possible
// to form B from A satisfying the given conditions
bool isPossible(string A, string B, int b, int m)
{
 
    // Vector to store the frequency
    // of characters in A
    vector S[26];
 
    // Vector to store the count of characters
    // used from a particular group of characters
    vector box(A.length(), 0);
 
    // Store the frequency of the characters
    for (int i = 0; i < A.length(); i++) {
        S[A[i] - 'a'].push_back(i);
    }
 
    int low = 0;
 
    for (int i = 0; i < B.length(); i++) {
        auto it = lower_bound(S[B[i] - 'a'].begin(),
                              S[B[i] - 'a'].end(), low);
 
        // If a character in B is not
        // present in A
        if (it == S[B[i] - 'a'].end())
            return false;
 
        int count = (*it) / b;
        box[count] = box[count] + 1;
 
        // If count of characters used from
        // a particular group of characters
        // exceeds m
        if (box[count] >= m) {
            count++;
 
            // Update low to the starting index
            // of the next group
            low = (count)*b;
        }
 
        // If count of characters used from
        // a particular group of characters
        // has not exceeded m
        else
            low = (*it) + 1;
    }
 
    return true;
}
 
// Driver code
int main()
{
    string A = "abcbbcdefxyz";
    string B = "acdxyz";
    int b = 5;
    int m = 2;
 
    if (isPossible(A, B, b, m))
        cout << "Yes";
    else
        cout << "No";
 
    return 0;
}


Java
// Java implementation of the approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function that returns true if it is
// possible to form B from A satisfying
// the given conditions
static boolean isPossible(String A, String B,
                          int b, int m)
{
     
    // List to store the frequency
    // of characters in A
    List> S = new ArrayList>();
 
    for(int i = 0; i < 26; i++)
        S.add(new ArrayList());
         
    // Vector to store the count of characters
    // used from a particular group of characters
    int[] box = new int[A.length()];
 
    // Store the frequency of the characters
    for(int i = 0; i < A.length(); i++)
    {
        S.get(A.charAt(i) - 'a').add(i);
    }
 
    int low = 0;
 
    for(int i = 0; i < B.length(); i++)
    {
        List indexes = S.get(
            B.charAt(i) - 'a');
 
        int it = lower_bound(indexes, low);
 
        // If a character in B is not
        // present in A
        if (it == indexes.size())
            return false;
 
        int count = indexes.get(it) / b;
        box[count] = box[count] + 1;
 
        // If count of characters used from
        // a particular group of characters
        // exceeds m
        if (box[count] >= m)
        {
            count++;
 
            // Update low to the starting index
            // of the next group
            low = (count) * b;
        }
 
        // If count of characters used from
        // a particular group of characters
        // has not exceeded m
        else
            low = indexes.get(it) + 1;
    }
 
    return true;
}
 
static int lower_bound(List indexes, int k)
{
    int low = 0, high = indexes.size() - 1;
 
    while (low < high)
    {
        int mid = (low + high) / 2;
        if (indexes.get(mid) < k)
            low = mid + 1;
        else
            high = mid;
    }
    return (indexes.get(low) < k) ? low + 1 : low;
}
 
// Driver code
public static void main(String[] args)
{
    String A = "abcbbcdefxyz";
    String B = "acdxyz";
    int b = 5;
    int m = 2;
 
    if (isPossible(A, B, b, m))
        System.out.println("Yes");
    else
        System.out.println("No");
}
}
 
// This code is contributed by jithin


Python3
# Python3 implementation of the approach
 
# Function that returns true if it is
# possible to form B from A satisfying
# the given conditions
def isPossible(A, B, b, m) :
       
    # List to store the frequency
    # of characters in A
    S = []
   
    for i in range(26) :
     
        S.append([])  
           
    # Vector to store the count of characters
    # used from a particular group of characters
    box = [0] * len(A)
   
    # Store the frequency of the characters
    for i in range(len(A)) :
     
        S[ord(A[i]) - ord('a')].append(i)
   
    low = 0
   
    for i in range(len(B)) :
     
        indexes = S[ord(B[i]) - ord('a')]
   
        it = lower_bound(indexes, low)
   
        # If a character in B is not
        # present in A
        if (it == len(indexes)) :
            return False
   
        count = indexes[it] // b
        box[count] = box[count] + 1
   
        # If count of characters used from
        # a particular group of characters
        # exceeds m
        if (box[count] >= m) :
         
            count += 1
   
            # Update low to the starting index
            # of the next group
            low = (count) * b
   
        # If count of characters used from
        # a particular group of characters
        # has not exceeded m
        else :
            low = indexes[it] + 1
   
    return True
   
def lower_bound(indexes, k) :
 
    low, high = 0, len(indexes) - 1
   
    while (low < high) :
     
        mid = (low + high) // 2
        if (indexes[mid] < k) :
            low = mid + 1
        else :
            high = mid
     
    if indexes[low] < k :
        return (low + 1)
    else :
        return low
         
A = "abcbbcdefxyz"
B = "acdxyz"
b = 5
m = 2
 
if (isPossible(A, B, b, m)) :
    print("Yes")
else :
    print("No")
 
    # This code is contributed by divyeshrabadiya07


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Function that returns true if it is
    // possible to form B from A satisfying
    // the given conditions
    static bool isPossible(string A, string B, int b, int m)
    {
          
        // List to store the frequency
        // of characters in A
        List> S = new List>();
      
        for(int i = 0; i < 26; i++)
        {
            S.Add(new List());
        }
              
        // Vector to store the count of characters
        // used from a particular group of characters
        int[] box = new int[A.Length];
      
        // Store the frequency of the characters
        for(int i = 0; i < A.Length; i++)
        {
            S[A[i] - 'a'].Add(i);
        }
      
        int low = 0;
      
        for(int i = 0; i < B.Length; i++)
        {
            List indexes = S[B[i] - 'a'];
      
            int it = lower_bound(indexes, low);
      
            // If a character in B is not
            // present in A
            if (it == indexes.Count)
                return false;
      
            int count = indexes[it] / b;
            box[count] = box[count] + 1;
      
            // If count of characters used from
            // a particular group of characters
            // exceeds m
            if (box[count] >= m)
            {
                count++;
      
                // Update low to the starting index
                // of the next group
                low = (count) * b;
            }
      
            // If count of characters used from
            // a particular group of characters
            // has not exceeded m
            else
                low = indexes[it] + 1;
        }
      
        return true;
    }
      
    static int lower_bound(List indexes, int k)
    {
        int low = 0, high = indexes.Count - 1;
      
        while (low < high)
        {
            int mid = (low + high) / 2;
            if (indexes[mid] < k)
                low = mid + 1;
            else
                high = mid;
        }
        return (indexes[low] < k) ? low + 1 : low;
    }
 
  static void Main() {
       
    string A = "abcbbcdefxyz";
    string B = "acdxyz";
    int b = 5;
    int m = 2;
  
    if (isPossible(A, B, b, m))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("No");
  }
}
 
// This code is contributed by divyesh072019


输出:
Yes