Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

สตริงย่อย Echo ที่แตกต่างกันใน C ++


สมมติว่าเรามีสตริง S; เราต้องหาจำนวนของสตริงย่อยที่ไม่ว่างที่ชัดเจนของ S ที่สามารถเขียนเป็นการต่อกันของสตริงบางตัวกับตัวมันเองได้

ดังนั้น หากอินพุตเป็นเหมือน "elloelloello" ผลลัพธ์จะเป็น 5 เนื่องจากมีสตริงย่อยบางตัว เช่น "ello", "lloe", "loel", "oell"

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -

  • เฉพาะ :=31

  • ม :=1^9 + 7

  • กำหนดฟังก์ชัน fastPow() ซึ่งจะยึดฐาน พลัง

  • res :=1

  • ในขณะที่กำลัง> 0 ทำ -

    • ถ้ากำลัง &1 ไม่ใช่ศูนย์ ดังนั้น −

      • res :=res * ฐาน

      • res :=res mod m

    • ฐาน :=ฐาน * ฐาน

    • ฐาน :=ตัวดัดแปลงฐาน 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

  • คืนค่าแฮชใหม่

  • จากวิธีหลัก ให้ทำดังต่อไปนี้ −

  • n :=ขนาดของข้อความ

  • กำหนดหนึ่งชุดและ

  • สำหรับการเริ่มต้น i :=2 เมื่อฉัน <=n อัปเดต i :=i + 2 ทำ −

    • temp :=สตริงว่าง

    • สำหรับการเริ่มต้น j :=0 เมื่อ j

      • temp :=temp + text[j]

    • hash1 :=createHashValue(ชั่วคราว, i / 2)

    • temp :=สตริงว่าง)

    • สำหรับการเริ่มต้น j :=i / 2 เมื่อ j

      • temp :=temp + text[j]

    • hash2 :=createHashValue(ชั่วคราว, 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