• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Porównywanie fragmentów z hashowaniem

Object Storage Arubacloud
0 głosów
131 wizyt
pytanie zadane 20 marca 2022 w C i C++ przez HUBSON2912 Obywatel (1,300 p.)

Witam, napisałem taki kod mający na celu porównać fragmentu dwóch napisów przez hashowanie.

//kod jest tylko do malych liter
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int p=29;  //liczba pierwsza
    long long mod=1000000007;  //liczba przez ktora sie moduluje
    long long pdox[1000];  //tablica z kolejnymi potegami p

    for(int i=0; i<100; i++)  // przypisanie wartosci do pdox
        pdox[i]=pow(p,i);
    int wartLit[123];  //tablica z kolejnymi wartosciami liter  a=1 b=2 c=3...
    for(int i='a'; i<='z'; i++)  //przypisanie do wartLit
        wartLit[i]=i-(int)'a'+1;

    string a,b;  //dwa napisy
    cin>>a>>b;
    int hashA[a.size()+10];  //tablica z kolejnymi wartosciami zahashowanych prefiksow dla slowa a
    int hashB[b.size()+10];  //tablica z kolejnymi wartosciami zahashowanych prefiksow dla slowa b
    for(int i=0; i<a.size(); i++)  //przypisanie kolejnych prefiksow dla a
        hashA[i]=wartLit[(int)(a[i])]*pdox[i];
    for(int i=0; i<b.size(); i++)  //przypisanie kolejnych prefiksow dla b
        hashB[i]=wartLit[(int)(b[i])]*pdox[i];

    int i,j,m,n,frHashA,frHashB;  //poczatek fragmenu a, koniec fragmentu a, poczatek fragmentu b, koniec fragmentu b, zahashowany fragment a, zahashowany fragment b
    cin>>i>>j>>m>>n;  //wczytanie poczatkow i koncow liczac od 1
    i--;  //minus jeden bo liczone od 1
    j--;
    m--;
    n--;

    if(i!=0)  //jesli poczatek fragmentu nie jest poczatkiem wyrazu trzeba odjac wartosc w poczatek minus 1
        frHashA=(((mod+hashA[j]-hashA[i-1])%mod)*pdox[m])%mod;
    else  //a jesli nie to nic nie trzeba robic bo wartosc w koncu jest rowna calemu fragmentowi
        frHashA=(((mod+hashA[j]/* -0 */)%mod)*pdox[m])%mod;

    if(m!=0)  //tak samo jak wyzej tylko dla napisu b
        frHashB=(((mod+hashB[n]-hashB[m-1])%mod)*pdox[i])%mod;
    else
        frHashB=(((mod+hashB[n])%mod)*pdox[i])%mod;

    if(frHashA==frHashB) //jesli zahashowane fragmenty sa sobie rowne to wyswietl "Tak" jesli nie to "Nie"
        cout<<"TAK";
    else
        cout<<"Nie";
    return 0;
}

Dla danych

asd
asd
1 3
1 3

działa poprawnie i wyświetla "Tak".

Jednak dla danych

asdf
zasd
1 3
2 4

wyświetla "Nie", pomimo że oba fragmenty są takie same.

Co powinienem poprawić, żeby kod działał poprawnie? (Wiem, że mogę kod jeszcze udoskonalić pod względem zużycia pamięci oraz zwiększając liczbę pierwszą p ale chodzi o samą zasadę.)

komentarz 21 marca 2022 przez Oscar Nałogowiec (29,320 p.)
Używasz tabelki pdox w ten sposób, że indeksujesz ją numerkiem literki w ciągu, więć co innego dostaniesz jak weźmiesz znaki 1..3 a co innego jak 2..4 bo do obliczeń wzięte będą inne elementy wspomnianej tabelki.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 409 wizyt
pytanie zadane 29 stycznia 2021 w PHP przez KrzysztofS Nowicjusz (170 p.)
0 głosów
2 odpowiedzi 374 wizyt
0 głosów
1 odpowiedź 130 wizyt

92,578 zapytań

141,426 odpowiedzi

319,653 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...