Utilizator:
Parola:
Am uitat parola... | Cont nou!


Articole Resurse Echipe Competiții Proiecte Forum DevBlogs Locuri de muncă GDROMag Issue#1 GDROCon 2007

 
Forum » Programare » Altele » Metoda eficienta de a cauta bytes




Pagina 1 din 1 [ 1 ]

Mesaj Info autor
    Postat la 06 Aug 2009 18:51:22    Subiect: Metoda eficienta de a cauta bytes
Jad info:

Jad:

Salut am si eu o intrebare. Care este cea mai eficienta metoda(rapida) de a cauta niste bytes intr-un fisier?
Am facut ceva simplu dar dureaza cautarea.

Cod sursă:
Nu am access acum la cod dar este in genul acesta:
int a=0;
char ch;
while (a<=numarul de biti care il are fisierul){
a++;
ch = fgetc(fp);
if(ch==primul bit){
ch = fgetc(fp);
if(ch==al doilea bit){
si tot asa ...
}
}
}
 

trebuie sa caut 6 bytes


Status:
Înregistrat pe:
13 Feb 2009 12:43:46
Vârsta: 24 ani
Mesaje: 12
Locatie: Braila
Programator junior

 
    Postat la 06 Aug 2009 19:06:39    Subiect: Re: Metoda eficienta de a cauta bytes
Deliverance info:

Deliverance:

Jad a scris:

Salut am si eu o intrebare. Care este cea mai eficienta metoda(rapida) de a cauta niste bytes intr-un fisier?
Am facut ceva simplu dar dureaza cautarea.

Cod sursă:
Nu am access acum la cod dar este in genul acesta:
int a=0;
char ch;
while (a<=numarul de biti care il are fisierul){
a++;
ch = fgetc(fp);
if(ch==primul bit){
ch = fgetc(fp);
if(ch==al doilea bit){
si tot asa ...
}
}
}
 

trebuie sa caut 6 bytes


Spui bytes dar in cod te referi la biti, voi presupune ca vrei sa cauti 6 bytes dupa cum mentionezi la sfarsit. Daca esti putin confuz in ceea ce inseamna byte sau bit, nu-i nimic: un byte are 8 bitzi si de aceea deseori un byte este numit octet(pentru ca el contine 8 bitzi, evident). Pe langa asta folosind functiile low level de acces la fisier sau pe cele high level(cele pe care le folosesti tu in cod) nu vei putea citi un numar de biti care nu este multiplu de 8, cu alte cuvinte tot timpul vei putea citi bytes intregi(unul, doi, cati vrei tu).
In primul rand pentru ca datele tale(fisierul) nu se afla in vreo structura de accelerare a cautarii nu prea sunt multe de facut. Poti insa imbunatati foarte mult cautarea liniara daca tii cont de urmatorul aspect: accesul la disc e costisitor si de aceea ar fi bine ca de fiecare data sa citesti mai mult de 1 byte(minimizand operatiile cu discul) si sa cauti informatiile tale in acel buffer. Pseoducodul ar putea arata astfel:

Cod sursă:

int a=0;
char data[1024]; // 1 kilobyte
while (!feof(f)){                     
int acutallyRead = fread(data,
                1, // dimensiunea unui element                                     
                 1024,   nr de elemente
                 f);
int i;
for (i=0; i)
if (data[i]==caracterul_meu)
{
    // proceseaza
}
}
 


Dupa cum vezi fread nu citeste tot timpul atatia bytes cati ii ceri tu ci cat poate. Uneori pot avea loc erori, alteori pur si simplu ai ajuns la sfarsitul fisierului si nu se mai poate umple buffer-ul cu 1024 de bytes.

In al doilea rand, daca ai cunoaste de la inceput datele atunci le-ai putea organiza intr-o structura ierarhica(sau tabela de dispersie), salva structura pe disc si apoi ai putea sa o citesti si sa cauti in ea de cate ori vrei, lucrurile ar putea merge mult mai repede, de obicei in O(logn) sau chiar O(1) folosind tabele hash si exploatand anumite particularitati ale datelor tale.

Ultima editare efectuată de Deliverance pe 06 Aug 2009 19:10:36; 5 editări în total


Status:
Înregistrat pe:
13 Oct 2006 10:05:37
Vârsta: 25 ani
Mesaje: 253
Locatie: Iasi , Romania
Programator

 
    Postat la 06 Aug 2009 19:20:56    Subiect: < fara subiect >
Jad info:

Jad:

Multumesc de reply dap ma refer la byte nu biti
Daca citesc bucati mai mari de date si le prelucrez in ram este mult mai rapid multumesc de solutie dar ma gandesc ca se poate intampla ceva de genul urmator:
citesc primul kilobyte fac cautarea daca nu gasesc cei 6 bytes citesc in continuare
dar daca se intampla ca primii 2 bytes sa se afle in bucata care o citesc prima data(sau a n oara) iar urmatorii 4 bytes se afla in bucata urmatoare ? Am sansa sa imi returneze fals desi valoarea este prezenta in fisier (as vrea sa fie gandit pentru fisiere cu marimi diferite)

Defapt este posibil sa fac un bool setat pe true daca s-a gasit primul/al 2-lea/al 3-lea byte si se termina bufferul de 1 kilobyte astfel pot cauta in continuare.

Multumesc inca o data de reply Deliverance.


Status:
Înregistrat pe:
13 Feb 2009 12:43:46
Vârsta: 24 ani
Mesaje: 12
Locatie: Braila
Programator junior

 
    Postat la 06 Aug 2009 21:50:39    Subiect: < fara subiect >
c0mas info:

c0mas:

pai daca fisierul nu e foarte mare ... poti sa-l citesti pe tot.

In solutia lui deliverance, ultima citire nu va fi de 1024 ... decat daca fisierul e multiplu de 1024 ... probabil trebuie sa vezi cat a citit la ultima citire.

Do what you love, money will follow!


Status:
Înregistrat pe:
19 Apr 2007 13:41:50
Vârsta: 35 ani
Mesaje: 337
Locatie: Bucuresti
Programator
Dream Builder Studios
 
    Postat la 06 Aug 2009 22:12:03    Subiect: < fara subiect >
Sir Game-a-lot info:

Sir Game-a-lot:

Incearca sa citesti blocuri de baiti si verifica intotdeauna cati baiti au fost cititi, si mentine un pointer la un set de 6 baiti care sunt baitii de detectie.

pseudo-cod:

Cod sursă:

#define NO_MAGIC_NUMBERS         1024
#define NO_MAGIC_NUMBERS_2     6

char buf[NO_MAGIC_NUMBERS];
char target_buf[NO_MAGIC_NUMBER_2]; //sau alocare dinamica

int index, target_index = 0;
while(!eof)
{
    index = 0;
    fread(f, NO_MAGIC_NUMBER, 1, buf);
    while(index < min(NO_MAGIC_NUMBER, actually read bytes)) // sau optimizat intr-o variabla operatia de min
    {
        if(buf[index] == target_buf[target_index])target_index++;
        else target_index = 0;
        if(target_index == NO_MAGIC_NUMBER_2)
            //found the 6 bytes so return true
    }
}
// daca am ajuns aici inseamna ca nu am gasit nimic
 


Daca nu ai de a face cu un sistem cu resurse restranse gen mobile, atunci aloca cat mai mult ram si cauta in ram, nu fa n operatii de citire aiurea. un 64K e rezonabil, depinzand de utilizarea acestui cod se poate si mai mult. Bonus daca te prinzi pt. ce cazuri codul de mai sus nu merge cum trebuie.

Ultima editare efectuată de Sir Game-a-lot pe 06 Aug 2009 22:16:34; 1 editări în total

Nine women working in perfect harmony can't have a baby in 1 month.


Status:
Înregistrat pe:
25 Aug 2007 18:20:41
Vârsta: 33 ani
Mesaje: 116
Locatie: Cluj-Napoca
Programator
Zamolxis Interactive
 
    Postat la 07 Aug 2009 03:47:17    Subiect: < fara subiect >
raicuandi info:

raicuandi:

grep in binary mode

Method 2: Move Your Mouse Pointer
If you move your mouse pointer continuously while the data is being returned to Microsoft Excel, the query may not fail. Do not stop moving the mouse until all the data has been returned to Microsoft Excel.


Status:
Înregistrat pe:
24 Mar 2007 21:02:40
Vârsta: 22 ani
Mesaje: 514
Locatie: Adelaide, Australia
Programator

 
    Postat la 07 Aug 2009 11:58:56    Subiect: < fara subiect >
jos8cal info:

jos8cal:

Citeste tot fisierul in memorie si proceseaza acolo. Latentele cu memoria sint cam de 250 de cicli (~80ns), pe cind cu diskul, un seek ajunge pina la 41 de milioane de cicli, adica 15ms pierdute.

Citirea de pe disk fa-o cu memory mapped files, ca sa eviti bufferele interne ale sistemului si sa faci copieri aiurea din bufferele system in bufferele tale. MMF este the way to go si atunci cind fisierul este prea mare ca sa poata fi tinut in RAM. Faci un window pe el pe care-l muti pina termini de citit.

Cit priveste algoritmii de cautare de bytes, problema este asemanatoare cu cautarea unui cuvint intr-un fisier, iar pentru asta exista algoritmi consacrati. Rabin-Karp, Knuth-Morris-Pratt, Boyer-Moore. Ultimul cred ca te-ar coafa cel mai bine.

"Sunt la dispozitia dumneavoastra ca sa realizam ceea ce avem de realizat." (Blaxxunromania)

Breviar de personalitati.


Status:
Înregistrat pe:
10 Jun 2007 22:08:36
Vârsta: ? ani
Mesaje: 190
Locatie:


 
    Postat la 07 Aug 2009 13:43:03    Subiect: Re:
Deliverance info:

Deliverance:

jos8cal a scris:

Citeste tot fisierul in memorie si proceseaza acolo. Latentele cu memoria sint cam de 250 de cicli (~80ns), pe cind cu diskul, un seek ajunge pina la 41 de milioane de cicli, adica 15ms pierdute.

Citirea de pe disk fa-o cu memory mapped files, ca sa eviti bufferele interne ale sistemului si sa faci copieri aiurea din bufferele system in bufferele tale. MMF este the way to go si atunci cind fisierul este prea mare ca sa poata fi tinut in RAM. Faci un window pe el pe care-l muti pina termini de citit.

Cit priveste algoritmii de cautare de bytes, problema este asemanatoare cu cautarea unui cuvint intr-un fisier, iar pentru asta exista algoritmi consacrati. Rabin-Karp, Knuth-Morris-Pratt, Boyer-Moore. Ultimul cred ca te-ar coafa cel mai bine.


Nu cred ca algoritmii de cautare pe siruri ar ajuta prea mult, patternul de cautat va avea tot timpul lungimea 1 (adica un byte). Complexitatea algoritmului va fi oricum O(M) adica lungimea fisierului in bytes. Acesti algoritmi ar ajuta atunci cand patternul ar fi mai lung de 1 byte.


Status:
Înregistrat pe:
13 Oct 2006 10:05:37
Vârsta: 25 ani
Mesaje: 253
Locatie: Iasi , Romania
Programator

 
    Postat la 07 Aug 2009 14:03:43    Subiect: < fara subiect >
jos8cal info:

jos8cal:

N-am inteles bine daca ce cauta el este un sir consecutiv de bytes sau nu, dar daca e consecutiv se face cu algoritmii lui peste de care ziceam, daca nu, se face cu un if().

"Sunt la dispozitia dumneavoastra ca sa realizam ceea ce avem de realizat." (Blaxxunromania)

Breviar de personalitati.


Status:
Înregistrat pe:
10 Jun 2007 22:08:36
Vârsta: ? ani
Mesaje: 190
Locatie:


 
    Postat la 07 Aug 2009 14:16:02    Subiect: Re:
Deliverance info:

Deliverance:

jos8cal a scris:

N-am inteles bine daca ce cauta el este un sir consecutiv de bytes sau nu, dar daca e consecutiv se face cu algoritmii lui peste de care ziceam, daca nu, se face cu un if().


Aaa, noi am tot discutat despre cum s-ar cauta un byte rapid. Desi daca ma gandesc bine chiar de ar cauta 6 bytes consecutivi, banuiesc ca l-ar interesa doar daca acestia exista sau nu exista si nu determinarea tuturor aparitiilor patternurilor de 6 bytes. Cred totusi ca ar fi over-kill implementarea unui algoritm avansat de pattern matching pentru 6 bytes Very Happy.


Status:
Înregistrat pe:
13 Oct 2006 10:05:37
Vârsta: 25 ani
Mesaje: 253
Locatie: Iasi , Romania
Programator

 
    Postat la 08 Aug 2009 17:44:22    Subiect: < fara subiect >
Jad info:

Jad:

multumesc de link-uri o sa ma uit peste ele.
As putea spune ca caut un string si anume OggS dar mai sunt inca 2 bytes care urmeaza (00 04 sau 00 05). In mod normal gasesc o singura data acest sir de 6 bytes.
Imediat dupa acesti biti urmeaza ceea ce ma intereseaza pe mine si anume sa aflu lungimea unui fisier ogg in milisecunde sau sub ce forma e salvat (un numar de genul 134957)

Ultima editare efectuată de Jad pe 08 Aug 2009 17:45:26; 1 editări în total


Status:
Înregistrat pe:
13 Feb 2009 12:43:46
Vârsta: 24 ani
Mesaje: 12
Locatie: Braila
Programator junior

 
    Postat la 08 Aug 2009 19:34:32    Subiect: < fara subiect >
Sir Game-a-lot info:

Sir Game-a-lot:

Vezi numa ca metoda mea clacheaza la un string gen "cocosu" cand ai:
"aasdfgasd_cococosu_egdfgd". Asta ca sa fie totul clar.

Nine women working in perfect harmony can't have a baby in 1 month.


Status:
Înregistrat pe:
25 Aug 2007 18:20:41
Vârsta: 33 ani
Mesaje: 116
Locatie: Cluj-Napoca
Programator
Zamolxis Interactive
 
    Postat la 09 Aug 2009 00:46:47    Subiect: < fara subiect >
Jad info:

Jad:

ma tot chinui la asta dar se pare ca nu vrea sa imi mearga prea de curand. Bytes astia trebuie sa ii gasesc in ordinea asta.
4F 67 67 53 00 04

Ultima editare efectuată de Jad pe 09 Aug 2009 00:47:28; 1 editări în total


Status:
Înregistrat pe:
13 Feb 2009 12:43:46
Vârsta: 24 ani
Mesaje: 12
Locatie: Braila
Programator junior

 
    Postat la 09 Aug 2009 01:13:16    Subiect: Re:
Sir Game-a-lot info:

Sir Game-a-lot:

Jad a scris:

ma tot chinui la asta dar se pare ca nu vrea sa imi mearga prea de curand. Bytes astia trebuie sa ii gasesc in ordinea asta.
4F 67 67 53 00 04


Ia-o logic, pune baitii de cautat intr-un array si incearca sa vezi cum ai gasi tu siru, daca ai fi in locul computerului. Ia-o pas cu pas, logic.

char TargetArray[6] = {0x4F, 0x67, ... };


Nine women working in perfect harmony can't have a baby in 1 month.


Status:
Înregistrat pe:
25 Aug 2007 18:20:41
Vârsta: 33 ani
Mesaje: 116
Locatie: Cluj-Napoca
Programator
Zamolxis Interactive
 
    Postat la 09 Aug 2009 11:46:32    Subiect: < fara subiect >
Jad info:

Jad:

ah mama is varza ... mersi mult ... nush de ce nu m-am gandit la un array (parca era o zicala la c++ cand te-ai blocat foloseste un array Smile )
Incerc sa vad ce imi iese Smile


Status:
Înregistrat pe:
13 Feb 2009 12:43:46
Vârsta: 24 ani
Mesaje: 12
Locatie: Braila
Programator junior

 

Pagina 1 din 1 [ 1 ]


Server time: 09:32:34 19.05.2012



[ Termeni si conditii | Contact | F.A.Q. | Funny Pictures ]

© 2006 - 2012 Copyright 7thFACTOR Entertainment - All rights reserved