C++ 将S1中S2的出现次数最大化,分别将N1和N2拼接次数

C++ 将S1中S2的出现次数最大化,分别将N1和N2拼接次数

以下文章讨论了在将字符串S1重复N1次,字符串S2重复N2次后,计算S2在S1中最大出现次数的方法。这是一种有趣的模式搜索问题。在本文中,我们采用了相对直观的解决方案。

问题陈述

任务是确定字符串S2在字符串S1中的最大非重叠出现次数。这些字符串会被多次拼接:S1重复n1次,S2重复n2次。

例子

输入

s1 = “abc”, s2 = “ac”, n1 = 4, n2 = 2

输出

2

解释

在将字符串S1连接四次后,我们得到字符串”abcabcabcabc”。同样,将字符串S2连接两次得到”acac”。通过观察,我们可以确定字符串S2作为一个非重叠子序列出现了两次于字符串S1中。因此,期望的输出是2。

输入

s1 = “”, s2 = “sfa”, n1 = 7, n2 = 8

输出

0

解释

由于s1是一个空字符串,自我连接n1次后,它仍然为空。因此,在s1中不会出现s2连接n2次的情况。

解决方案

该问题的一个可能解决方案是,我们首先分别将字符串s1和s2连接n1和n2次。这样可以确保字符串足够长以相互找到。然后,我们遍历s1中的字符,并检查它们是否等于相应的s2中的字符。如果它们相等,我们继续下一个字符。如果达到s2的长度,我们增加出现的次数。最后,我们返回出现的次数。下面提供的伪代码和C++程序实现了这个方法。

伪代码

  • 声明变量

string s1 – 要搜索的字符串

int n1 – s1连接的次数

string s2 – 要搜索的字符串

int n2 – s2连接的次数

  • 重复n1次

使用temp连接s1

  • 重复n2次

使用temp连接s2

  • 遍历s1中的字符

遍历s2中的字符

if current character of string s1 is identical to the current character of string s2,
   Increment j and i
Else,
   Increment i
If j reaches the length of s2,
   Increment the count of occurrences
  • 返回出现次数的计数

示例:C++程序

函数countOccurrence()计算s2在s1中出现的次数。n1和n2是s1和s2连接的次数。函数首先将s1与自身连接n1次,将s2与自身连接n2次。然后,它同时迭代s1和s2,检查是否匹配。如果找到匹配,函数增加出现计数器的值。函数返回计数器的最终值。还有一种情况是s2为空字符串。程序返回1,因为空字符串作为子序列出现一次。

示例

#include <iostream>
#include <map>
#include <string>
using namespace std;

// The purpose of this function is to determine the count of occurrences of string s2 within string s1.
// The variables n1 and n2 represent the number of times s1 and s2 are concatenated, respectively.
int countOccurrence(string s1, int n1, string s2, int n2){
   string temp = s1;
   while (n1 > 1){
      s1 += temp;
      n1--;
   }
   temp = s2;
   while (n2 > 1){
      s2 += temp;
      n2--;
   }
   int i = 0, j = 0, count = 0;
   while (i < s1.length()){
      j = 0;
      while (j < s2.length() && i < s1.length()){
         // In the event that the current character of s1 matches the current character of s2,
         // increase both j and i by one.
        if (s1[i] == s2[j]){
           j++;
           i++;
        }
        // Else move on to the next character in 's1'
        else{
           i++;
        }
        // If `j` reaches the length of `s2`, increment the count of occurrences.
        if (j == s2.length()){
           count++;
        }
      }
   }
   // Return the count of occurrences.
   return count;
}
int main(){
   string s1 = "abac";
   int n1 = 5;
   cout << "s1: " << s1 << " and n1: " << n1 <<endl;
   string s2 = "a";
   int n2 = 4;
   cout << "s2: " << s2 << " and n2: " << n2 << endl;
   if (s2.length() == 0){
   cout << 1 << endl;
   return 0;
   }
   cout << "count of occurrences of string s2 within string s1: "<< (countOccurrence(s1, n1, s2, n2));
   return 0;
}

输出

s1: abac and n1: 5
s2: a and n2: 4
count of occurrences of string s2 within string s1: 2

时间和空间复杂度分析

时间复杂度 :O(NM)

N和M分别是将字符串s1和s2重复连接n1和n2次后的长度。

空间复杂度 :O(N)

在连接字符串时使用了一个临时变量来存储字符串,临时字符串temp的长度为max(length(s1), length(s2))。

结论

本文提出了一种方法来最大化将字符串s2作为s1的子序列出现的次数。这是通过将s1和s2分别连接n1和n2次来实现的。我们通过适当的示例讨论了问题陈述。所提供的解决方案的时间复杂度为O(NM),且相当直观。可以使用Boyer Moore算法的变体更高效地解决这个问题,Boyer Moore算法是一种模式搜索算法。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程