C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++での個別のエコー部分文字列


文字列Sがあるとします。ある文字列とそれ自体の連結として記述できる、Sの明確な空でない部分文字列の数を見つける必要があります。

したがって、入力が「elloelloello」のような場合、「ello」、「lloe」、「loel」、「oell」などのサブストリングがあるため、出力は5になります。

これを解決するには、次の手順に従います-

  • プライム:=31

  • m:=1 ^ 9 + 7

  • 関数fastPow()を定義します。これには、base、power、

    が必要です。
  • res:=1

  • 電力>0の場合、実行-

    • power&1がゼロ以外の場合、-

      • res:=res * base

      • res:=res mod m

    • ベース:=ベース*ベース

    • base:=base mod m

    • パワー=パワー/2

  • 解像度を返す

  • 関数createHashValue()を定義します。これには、s、n、

    が必要です。
  • 結果:=0

  • 初期化i:=0の場合、i

    • 結果:=結果+(s [i] * fastPow(prime、i))

    • 結果:=結果mod m

  • 結果を返す

  • 関数recalculateHash()を定義します。これには、old、newC、oldHash、patLength、

    が必要です。
  • newHash:=oldHash-古い

  • newHash:=newHash * fastPow(prime、m-2)

  • newHash:=newHash +(newC * fastPow(prime、patLength-1))

  • newHash:=newHash mod m

  • newHashを返す

  • メインの方法から、次のようにします-

  • n:=テキストのサイズ

  • 1つのセットを定義します

  • 初期化i:=2の場合、i <=nの場合、更新i:=i + 2、do −

    • temp:=空の文字列

    • 初期化j:=0の場合、j

      • temp:=temp + text [j]

    • hash1:=createHashValue(temp、i / 2)

    • temp:=空の文字列)

    • 初期化j:=i / 2の場合、j

      • temp:=temp + text [j]

    • hash2:=createHashValue(temp、i / 2)

    • 初期化s1:=0、e1:=i / 2、s2:=i / 2、e2:=iの場合、e2 >

      • hash1がhash2と同じ場合、

        • hash1をansに挿入します

      • hash1:=recalculateHash(text [s1]、text [e1]、hash1、i / 2)

      • hash2:=recalculateHash(text [s2]、text [e2]、hash2、i / 2)

    • hash1がhash2と同じ場合、

      • hash1をansに挿入します

  • ansの戻りサイズ

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const lli prime = 31;
const lli m = 1e9 + 7;
class Solution {
   public:
   lli fastPow(lli base, lli power){
      lli res = 1;
      while (power > 0) {
         if (power & 1) {
            res = res * base;
            res %= m;
         }
         base *= base;
         base %= m;
         power >>= 1;
      }
      return res;
   }
   lli createHashValue(string s, lli n){
      lli result = 0;
      for (lli i = 0; i < n; i++) {
         result += (lli)(s[i] * fastPow(prime, i));
         result %= m;
      }
      return result;
   }
   lli recalculateHash(char old, char newC, lli oldHash, lli
   patLength){
      lli newHash;
      newHash = oldHash - (lli)old;
      newHash *= fastPow(prime, m - 2);
      newHash += ((lli)newC * fastPow(prime, patLength - 1));
      newHash %= m;
      return newHash;
   }
   int distinctEchoSubstrings(string text){
      int n = text.size();
      set<int> ans;
      for (int i = 2; i <= n; i += 2) {
         string temp = "";
         for (int j = 0; j < i / 2; j++) {
            temp += text[j];
         }
         int hash1 = createHashValue(temp, i / 2);
         temp = "";
         for (int j = i / 2; j < i; j++) {
            temp += text[j];
         }
         int hash2 = createHashValue(temp, i / 2);
         for (int s1 = 0, e1 = i / 2, s2 = i / 2, e2 = i; e2 < n;
         s1++, s2++, e1++, e2++) {
            if (hash1 == hash2) {
               ans.insert(hash1);
            }
            hash1 = recalculateHash(text[s1], text[e1], hash1,
            i / 2);
            hash2 = recalculateHash(text[s2], text[e2], hash2,
            i / 2);
         }
         if (hash1 == hash2) {
            ans.insert(hash1);
         }
      }
      return ans.size();
   }
};
main(){
   Solution ob;
   cout << (ob.distinctEchoSubstrings("elloelloello"));
}

入力

"elloelloello"

出力

5

  1. C++の整数の文字列で6で割り切れる部分文字列の数

    整数文字列が与えられ、整数形式で6で割り切れる部分文字列の数を決定する必要がある問題を見ていきます。入力は、数値(整数)で構成される文字列の形式であることに注意してください。それでも、分割可能性チェックは整数のみと見なして実行されます(文字列入力のASC​​II値は使用されません)。 入力 str = “648” 出力 説明 サブストリング「6」、「48」、および「648」は6で割り切れる。 入力 str = “38342” 出力 4 説明 サブストリング「3834」、「342」、「834」、および「42」は6で割り切

  2. C++を使用して文字列の部分文字列の数を見つける

    この記事では、特定の文字列に形成できるサブ文字列(空ではない)の数を見つけるためのアプローチについて学習します。 Input : string = “moon” Output : 10 Explanation: Substrings are ‘m’, ‘o’, ‘o’, ‘n’, ‘mo’, ‘oo’, ‘on’, ‘moo’, ‘oon’ and &