PDA

Visualizza la versione completa : [assembly x86] ricerca occorrenza in stringa


JErikaM
12-06-2012, 15:58
Eccomi qui con un altro problema .-. qui è proprio misero..non ha senso

in questo programma devo cercare le occorrenze della stringa 2 nella stringa 1
il programma funziona con tutte le stringhe che ho provato...tranne che con
"Sette scettici sceicchi sciocchi con la sciatica a Shanghai"
"icchi"
non capisco perchè..in quanto questa stringa mi pare a concetto uguale a "icchi sceicchi cane sceicchi cane icchi icchi icchi icchi cane" con la quale il programma funziona correttamente o.o
non riesco a trovare l'errore!!




#include <stdio.h>


void main()
{
#define MAX_LEN 100
//INPUT
char s1[] = "icchi sceicchi cane sceicchi cane icchi icchi icchi icchi cane"; //prima stringa
unsigned int lungS1 = sizeof(s1)-1;
char s2[] = "icchi"; //seconda stringa
unsigned int lungS2 = sizeof(s2)-1;
//OUTPUT
unsigned int posizioni[MAX_LEN];
unsigned int posizioniLen;

_asm
{
//azzeramento registri
XOR EAX,EAX //contiene il primo indice s1[ECX]
XOR EBX,EBX //è var temporanea che contiene l'indice da mettere se c'è l'occorrenza
XOR ECX,ECX //per scorrere s1
XOR EDX,EDX //per scorrere s2
XOR ESI,ESI //num occorrenze
XOR EDI,EDI //lo uso per la lunghezza

//se s1<s2 termino il programma perchè non ho occorrenze
MOV EDI,lungS1
CMP EDI,lungS2
JB fine

ciclo1:
MOV AL,s1[ECX] //sposto l'indice della stringa in AL (8bit)
MOV EBX,ECX //ci sposto l'indice che userò se trovo l'occorrenza (sarà l'indice che visualizzo nella stampa)
CMP AL,s2[EDX] //controllo il contenuto del primo indice di entrambe le stringhe
JNE nonuguali
uguali:
INC ECX //incremento gli indici delle due stringhe per scorrerle
INC EDX
MOV AL,s1[ECX] //sposto l'indice della stringa in AL (8bit)
CMP AL,s2[EDX] //controllo il contenuto dell'indice di entrambe le stringhe
JNE nonuguali
INC EDX //incremento EDX per controllare se sono arrivata alla fine del vettore
CMP EDX,lungS2 //confronto l'indice con la lunghezza si s2, se sono uguali ho terminato di scorrere
JE occorrenza
DEC EDX //decremento EDX siccome prima l'avevo incrementata
JNE uguali
occorrenza:
MOV posizioni[ESI*4],EBX //sposto l'indice in cui si trova l'occorrenza nel vettore. è *4 siccome un unsigned int è 4byte
INC ESI //incremento solo ora il numero delle occorrenze in modo da mettere EBX nella cella giusta
XOR EDX,EDX
JMP nonuguali2
nonuguali:
XOR EDX,EDX
CMP AL,s2[0] //nel caso in cui le due lettere sono diverse faccio questo controllo che controlla che la lettera in questione sia uguale alla prima della parola da cercare...così se mi trovo nel caso "sceicchi" e devo cercare "icchi", quando controllo la i che è diversa dalla mia h, vedo però che è uguale alla i della s2 quindi riparto col procedimento di controllo solito
JE ciclo1
nonuguali2:
INC ECX //incremento l'indice della stringa principale
CMP lungS1,ECX //confronto la lunghezza della sottostringa con il proprio indice, se sono uguali significa che ho finito tutta la stringa dove cercare le occorrenze
JE fine
XOR EDX,EDX //azzero l'indice della sottostringa per ripartire a controllare
JMP ciclo1
fine:
MOV posizioniLen,ESI //num occorrenze trovate
}
{

unsigned int i;
for (i=0;i<posizioniLen;i++)
printf("sottostringa in posizione-%d\n",posizioni[i]);
}

}





Help ç_çe grazie ancora!

oregon
12-06-2012, 16:03
Veramente anche con

char s1[] = "icchi sceicchi cane sceicchi cane icchi icchi icchi icchi cane"; //prima stringa
char s2[] = "icchi"; //seconda stringa

il programma va in crash ...

EDIT: un attimo ... il problema è che il codice è formattato male e il copia incolla non va bene ... modifica il tuo post in modo che sia correttamente utilizzabile ...

JErikaM
12-06-2012, 16:49
modificato!!!
:) grazie mille :)

oregon
12-06-2012, 16:51
Al posto di scrivere subito un codice funzionante, in prima battuta ti vorrei suggerire di semplificare il funzionamento del programma evitando situazioni "particolari" (come indicato in CMP AL,s2[0] ...).

L'algoritmo deve essere generico e semplice ...

JErikaM
12-06-2012, 17:02
eh ma quella situazione mi è necessaria..altrimenti il codice non funziona con stringhe dove ho delle occorrenze dopo lettere diverse
es CiCiao ,cercare Cia

oregon
12-06-2012, 17:08
Realizza questo controllo più semplicemente ...

Suddividi l'algoritmo in passo semplici ... (ad esempio, ma non precisamente ...)

1) confronta il "prossimo" carattere di A con il "prossimo" di B ...

2) se sono diversi passa al prossimo carattere di A (se esiste) e ricomincia dal primo di B in 1)

3) se sono uguali passa al prossimo di B (se esiste) ...

...

JErikaM
12-06-2012, 17:24
il mio algoritmo fa tutto queste cose...
senza quel controllo specifico (e quindi eliminando le modifiche relative)
mi trova tutte le occorrenze giuste in tutte le stringhe che non hanno un
CiCiao -> Cia
Sceicchi ->icchi

JErikaM
12-06-2012, 17:50
facendo debug su debug..ho notato che con la stringa degli sceicchi Sette scettici sceicchi sciocchi con la sciatica a Shanghai
se faccio
"Sette scettici sceicchi sciocchi con la sciatica a Shanghai " (ovvero spazio dopo ai)
funziona..
altrimenti no :dottò:


edit: sto controllando i controlli sull'ultimo carattere..dovrebbe essere l'errore

oregon
12-06-2012, 19:17
Guarda ... io farei così ...



_asm
{
MOV posizioniLen,0

XOR ESI,ESI
XOR EDI,EDI

nxtInStr1:
MOV AL,s1[ESI]
CMP AL,0
JZ endStr1

MOV BL,s2[EDI]
CMP BL,0
JZ endStr2

CMP AL,BL
JZ isCharEq

isCharNEq:
MOV EDI,-1

isCharEq:
INC ESI
INC EDI
JMP nxtInStr1

endStr2:
SUB ESI,lungS2
MOV EDX,posizioniLen
MOV posizioni[EDX*4],ESI
INC posizioniLen
JMP isCharNEq

endStr1:
}


molto semplicemente ...

JErikaM
13-06-2012, 10:47
sono riuscita ora a trovare l'errore nel mio codice, si trattava di un controllo sull'ultimo carattere... :spy:
tuttavia guardando il tuo sto cercando di semplificarlo un pò e qualcosa ho fatto :)
grazie mille ancora per tutto l'aiuto! sei molto gentile :)
spero un giorno di poter ricambiare l'aiuto!

Loading