Anagrame


vladx


Sal, am facut un program in C care sa afiseze daca doua cuvinte sunt anagrame una fata de cealalta.Programu merge daca nu folosesc goto, dar daca il bag in cod pt optimizarea codului programul nu mai merge din cauza evaluarii gresite a primului if.

Care e greseala?

CODSURSA
#include <stdio.h>
#include <string.h>

int main() {
     char s1[20],s2[20];
     int i,j,l1,l2,k,ok;
    
     printf("Introduceti primul cuvant: "); gets(s1);
     printf("Introduceti al doilea cuvant: "); gets(s2);
    
     ok=1;
     i=0;
     l1=strlen(s1) - 1;
     l2=strlen(s2) - 1;
    
     if ((l1 != l2) || strcmp(s1,s2)) {
             ok=0;
             goto t;
             }
     else while (i<=l1) {
            for (j=0,k=0; j<=l2; j++) {
                if (s1[i]==s2[j]) {
                                  k++;
                                  i++;
                                  }
                }          
            if (k!=l1) ok=0;
            else ok=1;
            }    
    
     t: if (ok) printf("DA");
     else printf("NU");
    
     getchar();
     return 0;
}



Multumesc pt ajutor! smile.gif
Madest
Intotdeauna o sa intre pe primul if cu exceptia cazului in care cuvintele sunt identice, iar daca sunt identice si intr-adevar ajunge pe else, la final ar trebui pusa conditia if (k!=l1+1) ca sa afiseze DA.
 
Darkangel
1.
CODSURSA
(l1 != l2) || strcmp(s1,s2)

Daca nu au aceeasi lungime ... nu vad de ce le mai compari

2.
CODSURSA
     if ((l1 != l2) || strcmp(s1,s2)) {
             ok=0;
             goto t;
             }
     else

Pentru ce ai pus goto ??? crezi ca dupa ce intra in "if" intra si in "else" ???

3.
pune ok pe zero si transforma if-ul in (l1 == l2) ... scapi de else

4.
CODSURSA
         while (i<=l1) {
            for (j=0,k=0; j<=l2; j++) {
                if (s1[i]==s2[j]) {
                                  k++;
                                  i++;
                                  }
                }          
            if (k!=l1) ok=0;
            else ok=1;

Codul asta sigur nu iti verifica daca doua cuvinte sunt anagrame. Poate nu stii ce inseamna "anagrama"


Cum am mai spus, pune ok pe 0 si testeaza egalitatea inainte sa intri in if, faci doi vectori in care sa contorizezi literele din fiecare cuvant si compara vectorii.
vladx
CITAT
Intotdeauna o sa intre pe primul if cu exceptia cazului in care cuvintele sunt identice, iar daca sunt identice si intr-adevar ajunge pe else, la final ar trebui pusa conditia if (k!=l1+1) ca sa afiseze DA.


Deci primul if este evaluat gresit in toate cazurile, ok luand mereu valoarea 0 si nu inteleg de ce... daca pun conditia k!=l1+1 ar trebui sa mearga din cauza ca ok e false mereu din primul [b]if[/b nu merge pt ca sare else-ul].Deci vreau sa inteleg de ce nu evalueaza bine if-ul asta.

CITAT
Daca nu au aceeasi lungime ... nu vad de ce le mai compari


Pt ca si daca au aceasi lungime dar sunt cuvinte identice atunci nu sunt anagrame normal. smile.gif

CITAT
Pentru ce ai pus goto ??? crezi ca dupa ce intra in "if" intra si in "else" ???


Adevarat aici n-are rost goto eu il pusesem cand codul nu avea si primul else ci doar while, samd. tongue.gif

CITAT
pune ok pe zero si transforma if-ul in (l1 == l2) ... scapi de else


Ori ca presupun adevarat sau false tot aia atata timp cat restu' e bine.

CITAT
Codul asta sigur nu iti verifica daca doua cuvinte sunt anagrame. Poate nu stii ce inseamna "anagrama"


Uite-te mai bine, algoritmul e bun in afara de conditia care mi-a corectat-o Madest. wink.gif
CITAT
Cum am mai spus, pune ok pe 0 si testeaza egalitatea inainte sa intri in if, faci doi vectori in care sa contorizezi literele din fiecare cuvant si compara vectorii.


Tare esti aici, pai de ce sa mai folosesc doi vectori cand oricum un string e deja un vector de caractere. smile.gif)
NumeDeCod
Primul if e bun daca ai mai pune un ! la strcmp() (vezi manualu' cu valoarea de return la functia asta), fiindca le compari doar daca au aceeasi lungime. Problema e la algoritmul care sa compare daca sunt anagrame. Ai luat in considerare cazul cand o litera poate sa apara de doua sau mai multe ori? Si cred ca numai tu stii ce incerci sa numeri acolo, nu uita ca esti intr-un while cand faci asa-zisele verificari... sunt mai multe metode ca sa realizezi ce vrei:

a) modifici al doilea cuvant (sau folosesti un vector auxiliar) pe masura ce gasesti cate o litera din primul. Daca nu mai gasesti, nu e anagrama. Complexitate o(n^2) ca si acum (aka e lent)
cool.gif parcurgi ambele cuvinte o singura data, la primul adaugi literele intr-un lookup table, la al doilea le scoti. Merge mai repede dar consumi mai mult spatiu.
c) sortezi ambele cuvinte (in-place) si le compari dupa. Viteza depinde de algoritmul de sortare.

@darkangel: daca faci cu inca doi vectori ce tii in ei cum ii compari la sfarsit?...
doriaal
CITAT
@darkangel: daca faci cu inca doi vectori ce tii in ei cum ii compari la sfarsit?...

Cred ca vroia sa faca cu vectori de aparitii a caracterelor - v1[s1[i]] , v2[s2[i]] tot incrementez cu 1 , si la sfarsit compar vectorii element cu element sau cu memcmp() .
vladx
CITAT (NumeDeCod @ 31st July 2009, 14:03) *
Primul if e bun daca ai mai pune un ! la strcmp() (vezi manualu' cu valoarea de return la functia asta), fiindca le compari doar daca au aceeasi lungime. Problema e la algoritmul care sa compare daca sunt anagrame. Ai luat in considerare cazul cand o litera poate sa apara de doua sau mai multe ori? Si cred ca numai tu stii ce incerci sa numeri acolo, nu uita ca esti intr-un while cand faci asa-zisele verificari... sunt mai multe metode ca sa realizezi ce vrei:

a) modifici al doilea cuvant (sau folosesti un vector auxiliar) pe masura ce gasesti cate o litera din primul. Daca nu mai gasesti, nu e anagrama. Complexitate o(n^2) ca si acum (aka e lent)
cool.gif parcurgi ambele cuvinte o singura data, la primul adaugi literele intr-un lookup table, la al doilea le scoti. Merge mai repede dar consumi mai mult spatiu.
c) sortezi ambele cuvinte (in-place) si le compari dupa. Viteza depinde de algoritmul de sortare.

@darkangel: daca faci cu inca doi vectori ce tii in ei cum ii compari la sfarsit?...


NumeDeCod algoritmul e bun.Deci avem doua cuvinte s1 si s2 si i,j initializatori pt compararea pe rand a literelor primului cuvant cu cele din al doilea, k numara cate litere din primu se regasesc in al doilea si cu ok presupunem ca sunt anagrame.Avem un while si un for si nu 2 for-uri deoarece atunci cand gaseste o litera creste k creste si i trecand la compararea urmatoarei litere din primul cuvant.Apoi dupa ce k a numarat cate litere se gasesc in ambele cuvinte, daca nu apar toate cuvintele atunci nu sunt anagrame altfel sunt.In final afiseaza DA pt ok true sau NU in caz contrar.Sper ca ai inteles!

Cum a spus Madest cu k!=l1+1 merge doar daca il initializez pe k inainte de ambele cicluri. wink.gif

Oricum mersi pt sugestia la functia strcmp(), merge asa. biggrin.gif


CITAT (doriaal @ 31st July 2009, 14:20) *
Cred ca vroia sa faca cu vectori de aparitii a caracterelor - v1[s1[i]] , v2[s2[i]] tot incrementez cu 1 , si la sfarsit compar vectorii element cu element sau cu memcmp() .


N-are rost de vreme ce s1 si s2 sunt deja vectori de tip char, de ce sa ne complicam. wink.gif
 
NumeDeCod
Eu cred ca ar trebui sa mai citesti odata ce am zis. Daca tu esti asa incapatanat sa sustii ca algoritmul tau minune merge asa cum e, presupun ca nu mai ai nevoie de forum, sugestii, etc.

Formateaza-ti codul sursa ca lumea si poate o sa observi cam pe unde apar la tine parantezele (de inceput si de final de bloc) pe la diversele cuvinte cheie. Sa stii ca modul in care iti pui tu de mana white-spaceurile n-are legatura cu modul in care compilatorul se uita la cod.
vladx
CITAT (NumeDeCod @ 31st July 2009, 14:46) *
Eu cred ca ar trebui sa mai citesti odata ce am zis. Daca tu esti asa incapatanat sa sustii ca algoritmul tau minune merge asa cum e, presupun ca nu mai ai nevoie de forum, sugestii, etc.

Formateaza-ti codul sursa ca lumea si poate o sa observi cam pe unde apar la tine parantezele (de inceput si de final de bloc) pe la diversele cuvinte cheie. Sa stii ca modul in care iti pui tu de mana white-spaceurile n-are legatura cu modul in care compilatorul se uita la cod.


Daca n-ai inteles algoritmul si nu vrei sa depanezi programul, eu unul nu iti mai explic o data.Conteaza ca acum merge punand ! la strcmp(). smile.gif


Madest


Pentru ce cuvinte ai testat tu programul?
vladx
CITAT (Madest @ 31st July 2009, 14:57) *
Pentru ce cuvinte ai testat tu programul?


Pt scara si caras.E obligatoriu ca ambele sa fie scrise cu minuscule sau majuscule. wink.gif
doriaal
ia incerca "caca"- "ccaa" , sau "maca" - "aacm" chiar si "a" , "a"
Madest
Incearca si pentru alte cuvinte, si daca merge pentru toate posteaza codul final.
vladx
CITAT (doriaal @ 31st July 2009, 15:07) *
ia incerca "caca"- "ccaa" , sau "maca" - "aacm" chiar si "a" , "a"


Merg toate astea in afara de "a" si "a" unde zice NU si e logic pt ca nu sunt anagrame. wink.gif

Deci programul merge bine si ia in considerare toate variantele asa cum trebuie. smile.gif
Madest
Inainte sa credem ca faci misto de noi pune si tu codul pe care testezi.
vladx
CITAT (Madest @ 31st July 2009, 15:18) *
Inainte sa credem ca faci misto de noi pune si tu codul pe care testezi.


Nu ma intereseaza daca ma credeti, daca vreti descoperiti singuri.
NumeDeCod
Ai o pauza de meditatie 7 zile. Noi ti-am raspuns ca nu merge cum trebuie tocmai fiindca am testat codul tau (nu ca nu ar fi vizibil cu ochiul liber if-ul ala flagrant bagat in while). Acum, daca tu i-ai adus niscaiva modificari pe ici si acolo, si anume in punctele esentiale, bravo tie. Numai nu ne fa pe noi prostii pamantului.
Reclama
In curand... autoevolution.ro

Teste, stiri, ghiduri, jurnale, forum si multe altele!
Aceasta este o versiune simplificatã a paginii originale. Pentru a vizita versiunea originala click aici.