infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva educationala => Subiect creat de: Bogdan-Cristian Tataroiu din Februarie 26, 2008, 18:01:29



Titlul: 005 Potrivirea sirurilor
Scris de: Bogdan-Cristian Tataroiu din Februarie 26, 2008, 18:01:29
Aici puteti discuta despre problema Potrivirea sirurilor (http://infoarena.ro/problema/strmatch).


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Victor-Nicolae Savu din Martie 17, 2008, 21:37:16
nush daca e ceva evident si sunt eu neatent, dar nu inteleg de ce iau SIGSEV. am luat cateva teste si acasa imi merg. e ceva cu evaluatorul sau e de la mine?  :?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Bogdan-Cristian Tataroiu din Martie 17, 2008, 21:41:39
Ai depasit limita de memorie..


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Victor-Nicolae Savu din Martie 17, 2008, 21:55:49
ms mult bogdan!


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Nezbeda Harald din Martie 31, 2008, 20:34:55
uitativa va rog si peste aceasta sursa  "job #168935"  si spunetimi cu as putea sa maresc viteza, pt ca eu nu ma incadrez in timp la 2 teste (banuiesc ca problema apare de la citirea datelor din fisier)  :sad:


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Grigorean din Martie 31, 2008, 21:22:31
Cu seekeoln in loc de eoln iei 80.

Am trimis doar citirea si de abia se incadreaza in 296 de ms, deci e clar ca trebuie sa citesti altfel. Incearca cu blockread (http://www.mirrorservice.org/sites/www.gnu-pascal.de/gpc/BlockRead.html).


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Fodor Gabor din Aprilie 02, 2008, 16:18:20
Am incercat sa implementez si sa testez cateva variatii cu o solutie cu hashuri.. si anumite lucruri nu mi se par clare  :-s
 - scanf mai repede decat getline?   :? am mai gasit informatii referitoare le problema, incepand cu versiunile GNU G++ 2.7.x  functiile IO din C++ sunt (mult) mai lente.. (iar testand aceeasi surse in VC++  rezultatele sunt opuse  - getline aprox. 2 ori mai rapida)..  limita e cam stransa.. oricum o solutie naiva nu se-ncadreaza in timp, deci mi se pare timpul de executie "fortata"
 - chiar daca doua valori hash asociati pt doi subsiruri sunt egali, totusi exista o sansa ca ele sa nu fie identice; de aceea, de obicei se implementeaza o testare "caracter-cu-caracter"; dar o astfel de sursa NU se incadreaza in timp...chiar daca verificarea e facuta pe baza a mai multori functii hash, solutia pierde din generalitatea sa, avand o complexitate O(N) "fortata" - si in unele cazuri chiar va fi mai optima decat KMP


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Savin Tiberiu din Aprilie 02, 2008, 18:43:17
pai kmp intra in timp fara nici o problema deci limita de timp nu e stransa. e numai buna ptr a impiedica solutiile cu hash ;)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Bogdan-Cristian Tataroiu din Aprilie 02, 2008, 18:53:52
Probabilistic sansele gasirii unei aparitii proaste sunt destul de mici. De exemplu daca iei 2 module in jurul valorilor de 1 miliard, respectiv 2 miliarde, prime intre ele, valoarea hashului este determinata unic modulo 2 * 10^18. Deci N (2 milioane) valori se distribuie asupra unui interval de 2 * 10^18. => e probabilitate mica sa gasesti aparitii proaste :). In situatii reale sunt folositi destui algoritmi de aproximare pentru ca raportul intre erori si timpul de rulare salvat este extrem de mic.

Sursa mea cu rabin karp intra in 0.2 nu credeam ca o sa fie probleme :P singura problema cu limita de timp e ca nu cred ca exista vreo sursa in pascal care sa ia 100.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cosmin-Mihai Tutunaru din Februarie 20, 2009, 22:58:59
Am si eu o problema cu sursa:

http://infoarena.ro/job_detail/263927?action=view-source

Imi greseste cateva teste, si nu vad de ce :(......

Le: am descoperit pana la urma ce greseam.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Iorga Dan din Aprilie 01, 2009, 21:23:54
Sunt si eu curios cum ar merge cu "blockread". Nu am inteles foarte bine sintaxa.Din cate am vazut eu, lungimea sirului nu trebuie sa fie mai mare de integer pentru a-l folosi.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: razyelx din Aprilie 06, 2009, 15:00:03
Puteti sa imi explicati si mie cum functioneaza KMP ca citesc aici in cartea lui Cerchez de vreo 4 ore si nu inteleg ce se face cu functia aia prefix, ce isneamna valorile din vectorul respectiv s.a.m.d.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Misarca din Aprilie 06, 2009, 15:06:48
valoare din pi[ i ] reprezinta cel mai lung prefix al sirului care e sufix al sirului S[ 1 ]S[ 2 ]...S[ i ].
De ex pt sirul a  a c b a  t a  a sirul de prefixe va arata asa.
                      0 1 0 0 1 0 1 2


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Paul-Dan Baltescu din Aprilie 07, 2009, 00:56:00
Puteti sa imi explicati si mie cum functioneaza KMP ca citesc aici in cartea lui Cerchez de vreo 4 ore si nu inteleg ce se face cu functia aia prefix, ce isneamna valorile din vectorul respectiv s.a.m.d.

Din cartea doamnei Cerchez.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: razyelx din Aprilie 07, 2009, 11:38:20
ahhh... scuze. Ai dreptate, cu toate ca am stat 3 ore sa inteleg de ce algoritmul KMP din cartea aia nu merge pe o problema realizand in final ca e gresit, fiind nevoit sa implementez solutia de pe infoarena.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Ranca Razvan din Aprilie 07, 2009, 14:49:52
Daca are cineva timp, va rog sa va uitati si pe sursa asta http://infoarena.ro/job_detail/300572 (http://infoarena.ro/job_detail/300572)

Imi da incorect pe 7 teste, si ma holbez la ea de vreo ora da tot nu vad care e cauza.

Mersi.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Bula Ionut din Aprilie 16, 2009, 17:47:31
Razvan (Haggis), fii atent la functia kmppre(). Esti sigur ca o faci corect? variabila j o scazi numai odata.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: A Andrei din Iulie 16, 2009, 12:04:42
Exista posibilitatea ca |A| > |B| ? Testul 49 asa cred ca este #-o


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Paul-Dan Baltescu din Iulie 16, 2009, 13:05:02
Daca nu se specifica nimic la restrictii, trebuie sa iei in considerare si acest caz.

Totusi, daca te-ai fi uitat pe ok-ul testului 49, ai fi vazut ca raspunsul e 1. (Testele sunt publice la arhiva educationala.)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: FMI - gr143 Timofte Ciprian din Ianuarie 12, 2010, 10:44:35
Am o mica problema la sursa Rabin Karp propusa.
La linia 55 si anume:
hash1 = ((hash1 - (B[i - NA] * P1) % MOD1 + MOD1) * P + B[ i]) % MOD1;

nu inteleg rostul acelui +MOD1 pentru ca atunci cand facem modulo MOD1 acel +MOD1 ar trebui sa fie echivalent cu +0.
Am incercat sa inlocuiesc respectiva linie cu:
hash1 = ((hash1 - (B[i - NA] * P1) % MOD1) * P + B[ i]) % MOD1; iar rezultatul a fost ca mi-ai iesit foarte putine teste.
Imi poate explica cineva cu ce influenteaza acel MOD1?

[editat de moderator] atentie la "[ i]" (fara spatiu), care este un tag special


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Mircea Dima din Ianuarie 12, 2010, 12:13:08
Am o mica problema la sursa Rabin Karp propusa.
La linia 55 si anume:
hash1 = ((hash1 - (B[i - NA] * P1) % MOD1 + MOD1) * P + B) % MOD1;

nu inteleg rostul acelui +MOD1 pentru ca atunci cand facem modulo MOD1 acel +MOD1 ar trebui sa fie echivalent cu +0.
Am incercat sa inlocuiesc respectiva linie cu:
hash1 = ((hash1 - (B[i - NA] * P1) % MOD1) * P + B) % MOD1; iar rezultatul a fost ca mi-ai iesit foarte putine teste.
Imi poate explica cineva cu ce influenteaza acel MOD1?



Tu ai scadere... daca restul iti da negativ nu e bine...asa ca adaugi un MOD1 ca sa devina pozitiv


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Grigorean din Ianuarie 12, 2010, 12:50:56
Limbajul nu este atat de inteligent incat sa isi dea seama ca 0 <= X < P si X-P sunt congruente modulo P. Cu alte cuvinte, sa presupunem ca lucrezi mod 7. In matematica 6 si -1 sunt congruente modulo P. Aici insa daca ai un numar negativ si aplici modulo, rezultatul nu va fi cel asteptat.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Tirca Bogdan din Mai 22, 2010, 18:25:21
Daca am de exemplu sirurile :

cse adcse se

si vreau sa vad care din ele este sufix pentru abadcse. Dupa ce formez numarul lui abadcse cu rabin karp, incerc sa scap de cate o litera de la inceput folosind aceeasi schema ca si la potrivire de siruri dar fara sa mai inmultesc cu baza si sa adun alt element.
sir3=(sir3-(c[j]*Pow1)%MOD1+MOD1)%MOD1
Nu e buna solutia sau gresesc eu ceva?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Aurelian Namascu din Iunie 30, 2010, 15:31:50
E normal ca atunci cand folosesc vector<int>(si deci ma bazez pe .size() pentru a-mi spune cate pozitii am gasit) si nu gasesc nici un sir sa primesc SIGSECV ? :'(


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Misarca din Iunie 30, 2010, 15:36:51
Nu am înțeles ce faci de primești SIGSEGV.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Tirca Bogdan din Iulie 01, 2010, 11:13:41
Zici ca daca vectorul e gol si tu apelezi .size() iti da eroarea aia? Daca e gol .size()=0,nu-ti da eroare


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Oancea Catalin din Februarie 06, 2011, 14:56:09
Poate sa se uite cineva pe sursa mea? Iau doar 14 puncte si am folosit KMP. http://infoarena.ro/job_detail/529187 (http://infoarena.ro/job_detail/529187)
Multumesc anticipat .  :)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Alexandrescu din Februarie 06, 2011, 17:49:20
Poate sa se uite cineva pe sursa mea? Iau doar 14 puncte si am folosit KMP. http://infoarena.ro/job_detail/529187 (http://infoarena.ro/job_detail/529187)
Multumesc anticipat .  :)

f.getline(P,100)? eu aia am sesizat cand ti-am deschis sursa... In rest daca a luat puncte inseamna ca aia e toata greseala  :D.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Oancea Catalin din Februarie 07, 2011, 09:44:14
:oops:    Mersi... sper sa nu mi se intample asa ceva si la olimpiada  ](*,)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Maxim Smith din Mai 19, 2012, 21:14:03
Asa o intrebare la algoritmul Rabin-Karp din sursa oficiala, de ce hash1 si hash2 se iau modulo cu 2 numere diferite?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Paul-Dan Baltescu din Mai 20, 2012, 09:21:53
Pentru ca daca ai folosi acelasi modulo, nu ai miscora deloc probabilitatea unei coliziuni.

Daca intrebi de ce se folosesc uneori doua sau mai multe hash-uri, raspunsul e urmatorul: daca functia ta hash genereaza numere uniform in intervalul [0, M1), atunci ai probabilitate 1/M1 pentru o coliziune. Daca mai adaugi o alta functie hash independenta de prima care returneaza numere uniform in intervalul [0, M2), atunci probabilitatea unei coliziuni scade la 1/M1 * 1/M2. Poti sa vezi tehnica asta ca si cum ai creste intervalul in care returneaza functia hash valorile la [0, M1*M2), dar in acelasi timp eviti calculul pe numere mari.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Maxim Smith din Mai 20, 2012, 09:42:38
Multumesc mult, am inteles  :)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 07, 2012, 19:56:57
Nu inteleg de ce nu vrea sami compileze am incercat si cu File *f=fopen... si cu freopen dar nu mere si imi zice ca nu gaste stdio.h am incercat deasemea cu cstdio si si ala zice ca nu mil gaseste.
http://infoarena.ro/job_detail/795221
http://infoarena.ro/job_detail/795220
http://infoarena.ro/job_detail/795217
vreo idee de ce se intampla asta?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Alexandru Popescu din Octombrie 07, 2012, 20:51:26
Dupa ce am experimentat putin cu sursa ta, am observat ca desi pe compilatorul meu codul tau nu da nici o eroare, pe compilatorul infoarena apare ca eroare spatiul lasat in directiva #include<cstdio >. Ca sa nu-ti mai dea eroare pur si simplu nu mai lasi spatiul acela si scrii #include<cstdio>.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 07, 2012, 21:11:43
mda.... ms dar sincer e o eroare un pic cam ridicola


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 07, 2012, 21:21:37
Bun... si de asemenea imi puteti da niste exemple pe care sursa mea nu functioneaza? ( nu vreau nici un motiv exact dc. nu functioneaza ci doar niste exemple ca sa ma chinui eu sa o rezolv )
http://infoarena.ro/job_detail/795262


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Dumitru Andrei Georgian din Octombrie 08, 2012, 06:50:50
Ai acces la atasamentele problemei. Intra la atasamente si descarca-ti testul pe care iti da incorect.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 08, 2012, 14:09:43
nu stiam asta ... multumesc :D


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 08, 2012, 20:31:23
ok dupa vreo 5 ore de incercari tot nu miam prea dat seama ca nu e bun ( e un pic cam greu cu testeke alea tinand cont ca is fooooarte lungi) nu am prea reusit sa fac nimic ... asa ca imi puteti da o mana de ajutor ? algoritmul e un boyer moore


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Dumitru Andrei Georgian din Octombrie 08, 2012, 20:55:28
Tu afisezi pe prima linie maxim 1000. In problema scrie ca trebuie sa afisezi pe prima linie numarul total de potriviri, iar pe a doua sa le afisezi doar pe primele 1000.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 08, 2012, 22:55:52
Ms, in afara de asta am observat ca la testul 6 imi sare peste un match ceea ce banui ca se intampla de la modul in care cresc i-ul  am incercat sa il fac in mai multe feluri dar nu prea reusesc cum sa obtin peste 38 de pct ( scz ca pun atatea intrebari dar is cam nou  ](*,) )


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Petenchea Alexandru din Octombrie 11, 2012, 12:58:51
Poti sa te uiti peste sursele exemplu care 100% sunt corecte. Si restul surselor sunt libere. Daca tot nu gasesti bug-ul, arunca o privire peste ele.  :P


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Mihai Visuian din Decembrie 22, 2012, 20:03:54
Am incercat sa rezolv problema prin Z-algorithm si iau 40 de puncte, nu inteleg ce nu e corect.

Later edit: am rezolvat. Nu am vazut ca trebuie afisate primele 1000 pentru testele mari.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Vlad Negura din Ianuarie 01, 2013, 19:01:51
salut 22ror
am incercat sa fac problema prin metoda Rabin Karp
am trimis o sursa facuta dupa exemplu oficial
http://infoarena.ro/job_detail/846223?action=view-source
si iau doar 40 puncte
apoi am incercat sa skimb hashul in unul foarte simplu (hash=(ord(a[1])+ord(a[2])...ord(a[n])) mod 100000021
plus am adaugat control manual in caz ca coincide hashul
si tot iau 40 puncte, dar e mai rapid decit cel oficial..  :?
http://infoarena.ro/job_detail/846204?action=view-source
help plz.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Ianuarie 17, 2013, 19:03:36
Aveti idee cum pot sa fac mai rapida implementarea la asta :
http://infoarena.ro/job_detail/856786
Fara sa folosesc un good sufix table ( vreau sa raman doar la un BMH nu la un BM)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Stratulat Alexandru din Martie 03, 2013, 22:09:55
Eu iau 60 de puncte pe problema cu TLE la 2 teste si fac direct cu strstr care este KMP deja optimizat din cate stiu eu. Care ar putea fi problema ? E mai rapid cu hashing ?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Andrei Grigorean din Martie 04, 2013, 14:20:58
Functia strstr() are complexitatea O(N^2), nu este KMP.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Pirtoaca George Sebastian din Martie 04, 2013, 14:29:08
Oricum, este foarte surprinzator ca a luat 60 de puncte cu strstr().  :shock:


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Stratulat Alexandru din Martie 04, 2013, 19:44:46
Bine ca mi-ati spus ca e O(n^2). Acum stiu ca trebuie sa invat KMP.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Stratulat Alexandru din Martie 08, 2013, 18:08:54
Am facut KMP si am luat 100, insa vreau sa fac si Rabin Karp. Am inteles foarte bine cum se face teoretic insa ceva nu imi iese la implementare. Aveti vreo idee ?

Cod:
#include <cstdio>
#include <cstring>
#define NMAX 2000001
#define min(a,b) a<b ? a:b
using namespace std;

char A[NMAX],B[NMAX];
int n,m,nr,a,b;
int Sol[NMAX];
int t[NMAX];

inline unsigned long putere(int x,int k,int MOD){

    if (k == 0)
        return 1;
   else if(k%2 == 0){
       a = putere(x,k/2,MOD);
        return a*a%MOD;
   }
   else{
        a = putere(x,k/2,MOD);
        b = a*a%MOD;
        return b*x % MOD;
   }
}

inline int match(char *T, char *P,int j){

    for(register int i=0;i<m;++i)
        if(T[i+j] != P[i])
            return 0;
return 1;
}

inline void Rabin_Karp(char *T,char *M,int d,int MOD){

    unsigned long h,P=0;
    n = strlen(T);
    m = strlen(M);

        t[0] =0;
        h = putere(d,m-1,MOD);
    for(register int i=0;i<m;++i){
        P = (d*P + M[i])% MOD;
        t[0] = (d*t[0] + T[i])%MOD;
}

    printf("%d\n",P);
    for(register int i=0;i<=n-m;++i){

        printf("%d\n",t[i]);
        if(P == t[i]){
            if(match(T,M,i))
                    Sol[++nr] = i;
                    printf("%d\n",i);
                  }

         t[i+1] = (d*(t[i] - T[i+1]*h) + T[i+m+1])%MOD;
        }
}

int main(){


freopen("strmatch.in","r",stdin);
freopen("strmatch.out","w",stdout);

fgets(B,sizeof(B),stdin);
fgets(A,sizeof(A),stdin);

    Rabin_Karp(A,B,256,100003);
    printf("%d\n",nr);
    for(register int i=1;i<=min(nr,1000);++i)
        printf("%d ",Sol[i]);

return 0;
}

Editat de admin: Foloseste tagul "code" atunci cand postezi surse.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cazacu Robert din Octombrie 31, 2013, 22:27:49
Ma chinui de ceva timp si nu inteleg ce nu e bine.Am incercat testele pe rand si imi dau rezultate corecte, dar evaluatorul nu imi da mai mult de 14 puncte si sincer nu pricep de ce.  :angry:

Daca se poate uita cineva peste sursa mea si sa-mi zica unde este greseala  :oops: .

http://www.infoarena.ro/job_detail/1019797


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: CHIRILA ADRIAN din Ianuarie 27, 2014, 17:55:15
Poate sa imi spuna cineva de ce obtin doar 40 de puncte pe sursa asta:http://www.infoarena.ro/job_detail/1093011?action=view-source (http://www.infoarena.ro/job_detail/1093011?action=view-source)?.
Pe restul testelor iau incorect.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Vasile Catana din Aprilie 15, 2014, 16:53:23
in pascal mai mult de 40 de puncte nu se primeste  :-'


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Mihai Calancea din Aprilie 15, 2014, 23:24:20
Am schimbat limita la 0.3.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Vasile Catana din Aprilie 20, 2014, 20:33:22
a intrat pe 100, multumesc mult :ok:


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Breahna David din Iunie 17, 2014, 19:55:11
Bună, m-am apucat și eu să rezolv problema dar nu iau decît 16 p..
 ](*,) ](*,) ](*,) :fighting: :fighting:
Deci, nu sunt sigur dacă am făcut kmp, dar am folosit functia prefix/sufix, la o dinamică pe sirul cautat, si apoi am parcurs odată sirul  in care se cauta, deci timpul O(n+m),, presupun,, nu iau TLE,, dar iau incorect.
Și nu pricep unde am greșit. pe Teste mici totul e ok.  :ok: :ok:
Dar pe testele din atașamente îmi dă greșeli.. și nunțeleg, unde greșesc .... ](*,) ](*,) ](*,) :fighting: :fighting:
Vă rog ajutațimăă..

Uitați și sursa.

http://www.infoarena.ro/job_detail/1198971

MULȚUMESC ANTICIPAT.. :peacefingers: :peacefingers:


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Shulghin Valera din August 11, 2014, 13:19:58
Cod:
#include <fstream>
#include <string>
#include <vector>

using namespace std;

ifstream f("strmatch.in");
ofstream g("strmatch.out");

string a,b;
vector<long> rez;
long i,poz=-1;

int main()
{
    getline(f,a);
    getline(f,b);

    poz=b.find(a,poz+1);
    while(poz!=string::npos)
    {
        rez.push_back(poz);
        poz=b.find(a,poz+1);
    }

    g<<rez.size()<<"\n";
    for(i=0;i<rez.size()&&i<1000;i++)
        g<<rez[i]<<" ";
    return 0;
}

Ma poate ajuta cineva sa gasesc ce am gresit ? Imi scrie Incorect la testele 13 49 si 50.

Am gasit greseala. Nu gasea daca subsirul aparea la inceput. Am initializat poz cu -1 su am luat 100 de puncte  :D


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Witsel Andrei din Decembrie 06, 2014, 19:01:21
vectorul pi reprezinta starile automatului, iar cu q doar parcurgem starile sau cum este?? ca nu am inteles foarte bine de ce nu scade q cu 1 ci se foloseste
while (q && A[q+1] != A)
            q = pi[q];
Adica am observat pe niste exemple ca asa este dar as vrea sa-mi explice cineva concret DE CE este asa.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Lucian Bicsi din Ianuarie 17, 2015, 12:09:50
Buna ziua! As dori putin ajutor... Am facut problema cu alg. Rabin-Karp in O(m+n), dar totusi imi da 40 de puncte. Mai mult decat atat, din testele ramase imi da TLE pe aprox. 90% din ele. Am comparat cu solutia prezentata si pot spune ca am mici optimizari, dar totusi TLE-ul e inevitabil. Daca v-ati putea uita putin pe sursa si sa imi spuneti daca vedeti ceva gresit, m-ar ajuta foarte mult. Daca nu, raman la KMP :))

(ignorati rand()-ul cand generez bazele)

Sursa: http://www.infoarena.ro/job_detail/1319652?action=view-source


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: George Marcus din Ianuarie 17, 2015, 14:05:09
Solutia oficiala foloseste int iar tu long long. Deci, solutia ta e mult mai inceata.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Adrian Pop din Martie 01, 2015, 23:54:22
NB pentru cei ce implementeaza rabin-karp:
`long int` pe calculatorul/compilatorul pe care se ruleaza testele are doar 32 de biti; Testele oficiale functioneaza bine mersi pe calculatorul meu iar de la evaluatorul IA primesc 0 (foloseam numere mari in loc sa calculez 2 hashuri)


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Russu Vadim din Aprilie 13, 2015, 14:25:32
Cu  str.find()  - 100 puncte :D


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Denis Mita din Mai 13, 2015, 00:49:03
Eu zic sa bagi str.find si la concursuri oficiale


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Cehan Petru din Iunie 20, 2015, 22:38:30
Salut tuturor!
Imi spune si mie cineva ce nu e bine? Tin sa precizez ca fac putin diferit functia esec si kmp ..Pica la testele 30 31 49 50..Dar ruleaza perfect pe ele in compilatorul meu. Uitati sursa: http://www.infoarena.ro/job_detail/1452478?action=view-source

Multumesc anticipat!


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Mercea Otniel din August 07, 2015, 14:16:55
Cod:
void make_prefix(void)
{
    int i, q = 0;
 
    for (i = 2, pi[1] = 0; i <= M; ++i)
    {
        while (q && A[q+1] != A[i])
            q = pi[q];
        if (A[q+1] == A[i])
            ++q;
        pi[i] = q;
    }
dc intotdeauna in while() se pune q=pi[q]? Din moment ce elementele nu sunt egale de ce nu se sare direct la q=0 deoarece de acolo incepe prefixul. As vrea o explicatie si un exemplu eventual care nu functioneaza corect pe ceea ce am spus eu


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: George Marcus din August 23, 2015, 22:11:08
Incearca sa cauti "xxy" in "xxxy".


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Razvan Dumitru din Februarie 08, 2016, 18:32:29
http://www.infoarena.ro/job_detail/1593570

80pct verificand pentru fiecare caracter din B.


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: andrei din Martie 06, 2016, 22:04:44
Oare ce gresesc la sursa asta(http://www.infoarena.ro/job_detail/1636050) folosind Rabin-Karp?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Soos Marton din Aprilie 04, 2016, 21:09:48
De ce îmi pică testele 30, 31, 49, 50 ? Le-am testat și mie mi-au ieșit corect.
http://www.infoarena.ro/job_detail/1674877


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Burcea Bogdan Madalin din Februarie 09, 2017, 16:46:10
Imi poate explica cineva de ce in sursa Rabin-Karp se alege baza pentru functia hash numarul 73?
Merge algoritmul si cu alte numere? Ce valori ar putea avea acestea tinand cont ca valorile sirului sunt intre 48 si 122 (0-z) ?
Conteaza ca e prim?


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Catalin Lupau din Iulie 03, 2017, 15:35:13
Nu ma ajuta cineva?
Am incercat sa rezolv problema si cu Rabin-Karp, dar si cu KMP. Maxim am luat 40 de puncte. Nu inteleg ce e gresit.

Rabin Karp:

##########

#include <iostream>
#include <fstream>
#include <cstring>
#define INFILE "strmatch.in"
#define OUTFILE "strmatch.out"
#define LMAX 2000000
#define NMAX 1000
#define base 101
#define modulo 10123
using namespace std;
ifstream in(INFILE);
ofstream out(OUTFILE);
//const int base=11;

char Cuvant[LMAX];
int CuvLen=0;
int HashCuv=0;
char String[LMAX];
int Hash=0;
int StringLen=0;
int Loc[NMAX];
int num=0;

int pow(int n,int e);

void Read(){
    in.getline(Cuvant,LMAX);
    CuvLen=strlen(Cuvant);
    in.getline(String,LMAX);
    StringLen=strlen(String);
    for(int i=0;i<CuvLen;i++){
        HashCuv+=pow(base,CuvLen-1-i)*int(Cuvant);

    }
    //HashCuv=HashCuv%modulo;
}

bool Egal(int seg){
    for(int i=0;i<CuvLen;i++){
        if(Cuvant!=String[seg+i]){
            //cout<<Cuvant<<String[seg+i]<<endl;
            return false;
        }
    }
    return true;
}

int pow(int n,int e){
    int r=1;
    for(int i=0;i<e;i++)
        r*=n;
    return r;
}

void RabinKarp(){
    Hash=0;
    for(int i=0;i<CuvLen;i++){
        int Num=pow(base,CuvLen-1-i);
        Hash=Hash+Num*int(String);
    }

    for(int i=0;i<=StringLen-CuvLen;i++){
        //cout<<Hash<<" "<<HashCuv<<endl;
        if(Hash==HashCuv){
            if(Egal(i)){
                Loc[num++]=i;
            }
        }
        Hash=base*(Hash-(double)String*pow(base,CuvLen-1))+String[i+CuvLen];
        //Hash=Hash%modulo;
    }
    out<<num<<"\n";
    for(int i=0;i<num;i++)
        out<<Loc<<" ";
}




int main()
{
    Read();
    RabinKarp();
    return 0;
}

#############

KMP:

############

#include <iostream>
#include <fstream>
#include <cstring>
#define INFILE "strmatch.in"
#define OUTFILE "strmatch.out"
#define LMAX 2000100
#define NMAX 1000

using namespace std;

void CrPrefTable(char pat[],int n,int P[]){
    P[0]=0;
    int border=0;
    for(int i=1;i<n;i++){
        while(border>0&&pat!=pat[border])
            border=P[border-1];
        if(pat==pat[border])
            border=border+1;
        else{
            P=0;
            border=0;
        }
        P=border;
    }
}

void KMP(char pat[],char text[]){

    int m=strlen(pat);
    int n=strlen(text);
    int Pi[m+n+1];
    char str[m+n+1];
    for(int i=0;i<m;i++)
        str=pat;
    str[m]='$';
    for(int i=0;i<n;i++){
        str[m+i+1]=text;
    }
    CrPrefTable(str,m+n+1,Pi);
    for(int i=m+1;i<m+n+1;i++){
        if(Pi==m){
            cout<<"found"<<endl;
            return;
        }
    }
    cout<<"not found"<<endl;
    return;
}
char Patt[LMAX];
char Text[LMAX];


int main()
{
    int N;
    //cin>>N;
    /*char trash[LMAX];
    cin.getline(trash,NMAX);*/
    N=1;
    cin.seekg('\n');
    for(int i=0;i<N;i++){

        cin.getline(Text,LMAX);
        cin.getline(Patt,LMAX);


        KMP(Patt,Text);
    }
    return 0;
}

#############


Titlul: Răspuns: 005 Potrivirea sirurilor
Scris de: Catalin Lupau din Iulie 03, 2017, 15:35:53
Nu ma ajuta cineva?
Am incercat sa rezolv problema si cu Rabin-Karp, dar si cu KMP. Maxim am luat 40 de puncte. Nu inteleg ce e gresit.

Rabin Karp:

##########

#include <iostream>
#include <fstream>
#include <cstring>
#define INFILE "strmatch.in"
#define OUTFILE "strmatch.out"
#define LMAX 2000000
#define NMAX 1000
#define base 101
#define modulo 10123
using namespace std;
ifstream in(INFILE);
ofstream out(OUTFILE);
//const int base=11;

char Cuvant[LMAX];
int CuvLen=0;
int HashCuv=0;
char String[LMAX];
int Hash=0;
int StringLen=0;
int Loc[NMAX];
int num=0;

int pow(int n,int e);

void Read(){
    in.getline(Cuvant,LMAX);
    CuvLen=strlen(Cuvant);
    in.getline(String,LMAX);
    StringLen=strlen(String);
    for(int i=0;i<CuvLen;i++){
        HashCuv+=pow(base,CuvLen-1-i)*int(Cuvant);

    }
    //HashCuv=HashCuv%modulo;
}

bool Egal(int seg){
    for(int i=0;i<CuvLen;i++){
        if(Cuvant!=String[seg+i]){
            //cout<<Cuvant<<String[seg+i]<<endl;
            return false;
        }
    }
    return true;
}

int pow(int n,int e){
    int r=1;
    for(int i=0;i<e;i++)
        r*=n;
    return r;
}

void RabinKarp(){
    Hash=0;
    for(int i=0;i<CuvLen;i++){
        int Num=pow(base,CuvLen-1-i);
        Hash=Hash+Num*int(String);
    }

    for(int i=0;i<=StringLen-CuvLen;i++){
        //cout<<Hash<<" "<<HashCuv<<endl;
        if(Hash==HashCuv){
            if(Egal(i)){
                Loc[num++]=i;
            }
        }
        Hash=base*(Hash-(double)String*pow(base,CuvLen-1))+String[i+CuvLen];
        //Hash=Hash%modulo;
    }
    out<<num<<"\n";
    for(int i=0;i<num;i++)
        out<<Loc<<" ";
}




int main()
{
    Read();
    RabinKarp();
    return 0;
}

#############

KMP:

############

#include <iostream>
#include <fstream>
#include <cstring>
#define INFILE "strmatch.in"
#define OUTFILE "strmatch.out"
#define LMAX 2000100
#define NMAX 1000

using namespace std;

void CrPrefTable(char pat[],int n,int P[]){
    P[0]=0;
    int border=0;
    for(int i=1;i<n;i++){
        while(border>0&&pat!=pat[border])
            border=P[border-1];
        if(pat==pat[border])
            border=border+1;
        else{
            P=0;
            border=0;
        }
        P=border;
    }
}

void KMP(char pat[],char text[]){

    int m=strlen(pat);
    int n=strlen(text);
    int Pi[m+n+1];
    char str[m+n+1];
    for(int i=0;i<m;i++)
        str=pat;
    str[m]='$';
    for(int i=0;i<n;i++){
        str[m+i+1]=text;
    }
    CrPrefTable(str,m+n+1,Pi);
    for(int i=m+1;i<m+n+1;i++){
        if(Pi==m){
            cout<<"found"<<endl;
            return;
        }
    }
    cout<<"not found"<<endl;
    return;
}
char Patt[LMAX];
char Text[LMAX];


int main()
{
    int N;
    //cin>>N;
    /*char trash[LMAX];
    cin.getline(trash,NMAX);*/
    N=1;
    cin.seekg('\n');
    for(int i=0;i<N;i++){

        cin.getline(Text,LMAX);
        cin.getline(Patt,LMAX);


        KMP(Patt,Text);
    }
    return 0;
}

#############