C++程序:查找既是前缀又是后缀的最长子串


假设我们有一个字符串s,我们需要找到s的最长前缀,该前缀也是s的后缀(不包括自身)。如果没有这样的前缀,则返回空字符串。

例如,如果输入是"madam",则输出为"m"。它有4个(不包括自身)前缀:"m","ma","mad","mada",以及4个后缀:"m","am","dam","adam"。最长的既是前缀又是后缀的子串是"m"。

为了解决这个问题,我们将遵循以下步骤:

  • 定义一个函数lps(),它将接收s作为参数。

  • n := s的长度

  • 定义一个大小为n的数组ret

  • j := 0, i := 1

  • 当i < n时,执行:

    • 如果s[i]等于s[j],则:

      • ret[i] := j + 1

      • (i加1)

      • (j加1)

    • 否则,如果s[i]不等于s[j],则:

      • 如果j > 0,则:

        • j := ret[j − 1]

      • 否则

        • (i加1)

  • 返回ret

  • 在主方法中执行以下操作:

  • n := s的长度

  • 如果n等于1,则:

    • 返回空字符串

  • 定义一个数组v = lps(s)

  • x := v[n − 1]

  • ret := 空字符串

  • 从i := 0开始,当i < x时,重复执行(i加1):

    • ret := ret + s[i]

  • 返回ret

让我们来看下面的实现来更好地理解:

示例

 在线演示

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   vector <int> lps(string s){
      int n = s.size();
      vector<int> ret(n);
      int j = 0;
      int i = 1;
      while (i < n) {
         if (s[i] == s[j]) {
            ret[i] = j + 1;
            i++;
            j++;
         }
         else if (s[i] != s[j]) {
            if (j > 0)
            j = ret[j - 1];
            else {
               i++;
            }
         }
      }
      return ret;
   }
   string longestPrefix(string s) {
      int n = s.size();
      if (n == 1)
      return "";
      vector<int> v = lps(s);
      int x = v[n - 1];
      string ret = "";
      for (int i = 0; i < x; i++) {
         ret += s[i];
      }
      return ret;
   }
};
main(){
   Solution ob;
   cout << (ob.longestPrefix("helloworldhello"));
}

输入

"helloworldhello"

输出

hello

更新于:2020年12月15日

444 次浏览

启动您的职业生涯

完成课程后获得认证

开始学习
广告