C ++中最长的重复子字符串

假设我们有一个字符串S,请考虑出现2次或更多次的所有重复的连续子字符串。(发生的情况可能会重叠。),我们必须找到具有最长可能长度的重复子字符串。如果没有这样的子字符串,则返回一个空白字符串。由于答案可能非常大,因此请返回mod 10 ^ 9 + 7。

因此,如果输入像“ ababbaba”,那么输出将是“ bab”

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

  • m:= 1e9 + 7

  • 定义一个函数add(),这将需要a,b,

  • return((a mod m)+(b mod m))mod m

  • 定义一个函数sub(),这将需要a,b,

  • return((a mod m)-(b mod m)+ m)mod m

  • 定义一个函数mul(),这将需要a,b,

  • return((a mod m)*(b mod m))mod m

  • 定义阵列幂

  • 定义一个函数ok(),它将取x,s,

  • 如果x等于0,则-

    • 返回空字符串

  • 定义一个称为哈希的映射

  • 当前:= 0

  • 对于初始化i:= 0,当i <x时,更新(将i增加1),执行-

    • 当前:=添加(mul(当前,26),s [i]-'a')

  • hash [current]:=定义一个数组(1,0)

  • n:= s的大小

  • 对于初始化i:= x,当i <n时,更新(将i增加1),执行-

    • 在哈希的末尾插入i-x +1 [当前]

    • 对于在hash [current]中的所有-

    • 将s的子字符串从它返回到x-1

    • 如果从s到x-1的s子字符串与从i-x +1到x-1的s的子字符串相同,则-

    • 当前:= sub(当前,mul(幂[x-1],s [i-x]-'a'))

    • 当前:=添加(mul(当前,26),s [i]-'a')

    • 如果count是hash的成员,则-

    • 除此以外

    • 返回空字符串

    • 从主要方法中,执行以下操作-

    • ret:=空字符串

    • n:= S的大小

    • power:=定义一个大小为n的数组,并用1填充它

    • 对于初始化i:= 1,当i <n时,更新(将i增加1),-

      • power [i]:= mul(power [i-1],26)

    • 低:= 0,高:= n-1

    • 当低<=高时,执行-

      • 如果temp的大小> ret的大小,则-

      • 低:=中+ 1

      • ret:=临时

      • 高:=中-1

      • 中:=低+(高-低)/ 2

      • 温度:= ok(mid,S)

      • 如果temp的大小等于0,则-

      • 除此以外

      • 返回ret

      让我们看下面的实现以更好地理解-

      示例

      #include <bits/stdc++.h>
      using namespace std;
      typedef long long int lli;
      class Solution {
         public:
         int m = 1e9 + 7;
         int add(lli a, lli b){
            return ((a % m) + (b % m)) % m;
         }
         int sub(lli a, lli b){
            return ((a % m) - (b % m) + m) % m;
         }
         int mul(lli a, lli b){
            return ((a % m) * (b % m)) % m;
         }
         vector<int> power;
         string ok(int x, string s){
            if (x == 0)
            return "";
            unordered_map<int, vector<int> > hash;
            lli current = 0;
            for (int i = 0; i < x; i++) {
               current = add(mul(current, 26), s[i] - 'a');
            }
            hash[current] = vector<int>(1, 0);
            int n = s.size();
            for (int i = x; i < n; i++) {
               current = sub(current, mul(power[x - 1], s[i - x] -
               'a'));
               current = add(mul(current, 26), s[i] - 'a');
               if (hash.count(current)) {
                  for (auto& it : hash[current]) {
                     if (s.substr(it, x) == s.substr(i - x + 1, x)) {
                        return s.substr(it, x);
                     }
                  }
               } else {
                  hash[current].push_back(i - x + 1);
               }
            }
            return "";
         }
         string longestDupSubstring(string S){
            string ret = "";
            int n = S.size();
            power = vector<int>(n, 1);
            for (int i = 1; i < n; i++) {
               power[i] = mul(power[i - 1], 26);
            }
            int low = 0;
            int high = n - 1;
            while (low <= high) {
               int mid = low + (high - low) / 2;
               string temp = ok(mid, S);
               if (temp.size() == 0) {
                  high = mid - 1;
               } else {
                  if (temp.size() > ret.size())
                  ret = temp;
                  low = mid + 1;
               }
            }
            return ret;
         }
      };
      main(){
         Solution ob;
         cout << (ob.longestDupSubstring("ababbaba"));
      }

      输入值

      "ababbaba"

      输出结果

      bab