📌  相关文章
📜  通过分别连接 N1 和 N2 次,将 S1 中 S2 作为子序列的出现次数最大化

📅  最后修改于: 2021-09-06 06:51:37             🧑  作者: Mango

给定两个字符串S1,S2的长度NM分别与两个正整数N1N2中,任务是找到的最大计数非重叠通过连接字符串s1其是等于S2 S1的子序列中,n1倍和字符串s2n2次。

例子:

方法:这个问题可以通过检查一个字符串是否是另一个字符串的子序列的概念来解决。
请按照以下步骤解决问题:

  • 遍历字符串S和检查的字符,如果所有S2的字符存在的字符串S1或不在家。如果发现为假,则S1 的此类子序列不可能通过将字符串S1 , N1次和字符串S2 , N2次连接而使其等于S2
  • 循环迭代字符串S1的字符N1次。对于每个i索引,检查S1 的任何子序列是否存在直到i索引,即等于S2或不。如果发现为真,则增加计数。
  • 最后,执行上述操作后,将除以N2得到的计数打印为所需答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
 
using namespace std;
 
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
int getMaxRepetitions(string s1, int n1,
                      string s2, int n2)
{
 
  int temp1[26] = {0}, temp2[26] = {0};
 
  for(char i:s1) temp1[i - 'a']++;
 
  for(char i:s2) temp2[i - 'a']++;
 
  for(int i = 0; i < 26; i++)
  {
    if(temp2[i] > temp1[i]) return 0;
  }
 
  // Stores number of times
  // s1 is traversed
  int s1_reps = 0;
 
  // Stores number of times
  // s2 is traversed
  int s2_reps = 0;
 
  // Mapping index of s2 to number
  // of times s1 and s2 are traversed
  map > s2_index_to_reps;
  s2_index_to_reps[0] = {0, 0};
 
  // Stores index of s1 circularly
  int i = 0;
 
  // Stores index of s2 circularly
  int j = 0;
 
  // Traverse the string s1, n1 times
  while (s1_reps < n1){
 
    // If current character of both
    // the string are equal
    if (s1[i] == s2[j])
 
      // Update j
      j += 1;
 
    // Update i
    i += 1;
 
    // If j is length of s2
    if (j == s2.size())
    {
      // Update j for
      // circular traversal
      j = 0;
 
      // Update s2_reps
      s2_reps += 1;
    }
 
    // If i is length of s1
    if (i == s1.size())
    {
 
      // Update i for
      // circular traversal
      i = 0;
 
      // Update s1_reps
      s1_reps += 1;
 
      // If already mapped j
      // to (s1_reps, s2_reps)
      if (s2_index_to_reps.find(j) !=
          s2_index_to_reps.end())
        break;
 
      // Mapping j to (s1_reps, s2_reps)
      s2_index_to_reps[j] = {s1_reps, s2_reps};
    }
  }
 
  // If s1 already traversed n1 times
  if (s1_reps == n1)
    return s2_reps / n2;
 
  // Otherwis, traverse string s1 by multiple of
  // s1_reps and update both s1_reps and s2_reps
  int initial_s1_reps = s2_index_to_reps[j].first ,
  initial_s2_reps = s2_index_to_reps[j].second;
  int loop_s1_reps = s1_reps - initial_s1_reps;
  int loop_s2_reps = s2_reps - initial_s2_reps;
  int loops = (n1 - initial_s1_reps);
 
 
  // Update s2_reps
  s2_reps = initial_s2_reps + loops * loop_s2_reps;
 
  // Update s1_reps
  s1_reps = initial_s1_reps + loops * loop_s1_reps;
 
  // If s1 is traversed less than n1 times
  while (s1_reps < n1)
  {
 
    // If current character in both
    // the string are equal
    if (s1[i] == s2[j])
 
      // Update j
      j += 1;
 
    // Update i
    i += 1;
 
    // If i is length of s1
    if (i == s1.size())
    {
 
      // Update i for circular traversal
      i = 0;
 
      // Update s1_reps
      s1_reps += 1;
    }
 
    // If j is length of ss
    if (j == s2.size())
    {
 
      // Update j for circular traversal
      j = 0;
 
      // Update s2_reps
      s2_reps += 1;
    }
  }
  return s2_reps / n2;
}
 
// Driver Code
int main()
{
  string s1 = "acb";
  int n1 = 4;
  string s2 = "ab";
  int n2 = 2;
 
  cout << (getMaxRepetitions(s1, n1, s2, n2));
 
  return 0;
}
 
// This code is contributed by mohit kumar 29.


Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Function to count maximum number of
// occurrences of s2 as subsequence in s1
// by concatenating s1, n1 times and s2, n2 times
static int getMaxRepetitions(String s1, int n1,
                             String s2, int n2)
{
    int temp1[] = new int[26], temp2[] = new int[26];
 
    for(char i : s1.toCharArray())
        temp1[i - 'a']++;
 
    for(char i : s2.toCharArray())
        temp2[i - 'a']++;
 
    for(int i = 0; i < 26; i++)
    {
        if (temp2[i] > temp1[i])
            return 0;
    }
 
    // Stores number of times
    // s1 is traversed
    int s1_reps = 0;
 
    // Stores number of times
    // s2 is traversed
    int s2_reps = 0;
 
    // Mapping index of s2 to number
    // of times s1 and s2 are traversed
    HashMap s2_index_to_reps = new HashMap<>();
    s2_index_to_reps.put(0, new int[] { 0, 0 });
 
    // Stores index of s1 circularly
    int i = 0;
 
    // Stores index of s2 circularly
    int j = 0;
 
    // Traverse the string s1, n1 times
    while (s1_reps < n1)
    {
         
        // If current character of both
        // the string are equal
        if (s1.charAt(i) == s2.charAt(j))
 
            // Update j
            j += 1;
 
        // Update i
        i += 1;
 
        // If j is length of s2
        if (j == s2.length())
        {
             
            // Update j for
            // circular traversal
            j = 0;
 
            // Update s2_reps
            s2_reps += 1;
        }
 
        // If i is length of s1
        if (i == s1.length())
        {
             
            // Update i for
            // circular traversal
            i = 0;
 
            // Update s1_reps
            s1_reps += 1;
 
            // If already mapped j
            // to (s1_reps, s2_reps)
            if (!s2_index_to_reps.containsKey(j))
                break;
 
            // Mapping j to (s1_reps, s2_reps)
            s2_index_to_reps.put(
                j, new int[] { s1_reps, s2_reps });
        }
    }
 
    // If s1 already traversed n1 times
    if (s1_reps == n1)
        return s2_reps / n2;
 
    // Otherwis, traverse string s1 by multiple of
    // s1_reps and update both s1_reps and s2_reps
    int initial_s1_reps = s2_index_to_reps.get(j)[0],
        initial_s2_reps = s2_index_to_reps.get(j)[1];
    int loop_s1_reps = s1_reps - initial_s1_reps;
    int loop_s2_reps = s2_reps - initial_s2_reps;
    int loops = (n1 - initial_s1_reps);
 
    // Update s2_reps
    s2_reps = initial_s2_reps + loops * loop_s2_reps;
 
    // Update s1_reps
    s1_reps = initial_s1_reps + loops * loop_s1_reps;
 
    // If s1 is traversed less than n1 times
    while (s1_reps < n1)
    {
         
        // If current character in both
        // the string are equal
        if (s1.charAt(i) == s2.charAt(j))
 
            // Update j
            j += 1;
 
        // Update i
        i += 1;
 
        // If i is length of s1
        if (i == s1.length())
        {
             
            // Update i for circular traversal
            i = 0;
 
            // Update s1_reps
            s1_reps += 1;
        }
 
        // If j is length of ss
        if (j == s2.length())
        {
             
            // Update j for circular traversal
            j = 0;
 
            // Update s2_reps
            s2_reps += 1;
        }
    }
    return s2_reps / n2;
}
 
// Driver Code
public static void main(String[] args)
{
    String s1 = "acb";
    int n1 = 4;
    String s2 = "ab";
    int n2 = 2;
 
    System.out.println(
        getMaxRepetitions(s1, n1, s2, n2));
}
}
 
// This code is contributed by Kingash


Python3
# Python3 program for the above approach
 
# Function to count maximum number of
# occurrences of s2 as subsequence in s1
# by concatenating s1, n1 times and s2, n2 times
def getMaxRepetitions(s1, n1, s2, n2):
 
    # If all the characters of s2 are not present in s1
    if any(c for c in set(s2) if c not in set(s1)):
        return 0
 
    # Stores number of times
    # s1 is traversed
    s1_reps = 0
 
    # Stores number of times
    # s2 is traversed
    s2_reps = 0
 
    # Mapping index of s2 to number
    # of times s1 and s2 are traversed
    s2_index_to_reps = { 0 : (0, 0)}
 
    # Stores index of s1 circularly
    i = 0
 
    # Stores index of s2 circularly
    j = 0
 
    # Traverse the string s1, n1 times
    while s1_reps < n1:
 
        # If current character of both
        # the string are equal
        if s1[i] == s2[j]:
         
            # Update j
            j += 1
 
        # Update i   
        i += 1
 
        # If j is length of s2
        if j == len(s2):
             
            # Update j for
            # circular traversal
            j = 0
 
            # Update s2_reps
            s2_reps += 1
 
        # If i is length of s1
        if i == len(s1):
 
            # Update i for
            # circular traversal
            i = 0
 
            # Update s1_reps
            s1_reps += 1
 
            # If already mapped j
            # to (s1_reps, s2_reps)
            if j in s2_index_to_reps:
                break
 
            # Mapping j to (s1_reps, s2_reps)   
            s2_index_to_reps[j] = (s1_reps, s2_reps)
 
    # If s1 already traversed n1 times
    if s1_reps == n1:
        return s2_reps // n2
 
    # Otherwis, traverse string s1 by multiple of
    # s1_reps and update both s1_reps and s2_reps
 
    initial_s1_reps, initial_s2_reps = s2_index_to_reps[j]
    loop_s1_reps = s1_reps - initial_s1_reps
    loop_s2_reps = s2_reps - initial_s2_reps
    loops = (n1 - initial_s1_reps)
 
 
    # Update s2_reps
    s2_reps = initial_s2_reps + loops * loop_s2_reps
 
    # Update s1_reps
    s1_reps = initial_s1_reps + loops * loop_s1_reps
 
    # If s1 is traversed less than n1 times
    while s1_reps < n1:
 
        # If current character in both
        # the string are equal
        if s1[i] == s2[j]:
 
            # Update j
            j += 1
 
        # Update i   
        i += 1
         
        # If i is length of s1
        if i == len(s1):
 
            # Update i for circular traversal
            i = 0
 
            # Update s1_reps
            s1_reps += 1
             
        # If j is length of ss
        if j == len(s2):
 
            # Update j for circular traversal
            j = 0
 
            # Update s2_reps
            s2_reps += 1
 
    return s2_reps // n2
 
# Driver Code
if __name__ == '__main__':
    s1 = "acb"
    n1 = 4
    s2 = "ab"
    n2 = 2
 
    print(getMaxRepetitions(s1, n1, s2, n2))


输出:
2

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live