001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004:
005: // struct per memorizzare coppie di parole
006: // di fatto si usera' un array di quese struct man mano allocato dinamicamente
007: // del tutto lecito sarebbe stato anche usare un semplice array di stringhe in cui all'indice pari trovavo una delle parole della coppia
008: // e al consecutivo indice dispari l'altra
009: struct coppia
010: {
011: char *parola1;
012: char *parola2;
013: };
014:
015: // funzioni che uso come da testo, passo ogni volta una singola coppia
016: int check_palindromi(struct coppia);
017: int check_anagrammi(struct coppia);
018:
019: int main(int argc, char **argv){
020:
021: FILE *fp = fopen("parole.txt", "r");
022: if(!fp)
023: {
024: perror("");
025: exit(EXIT_FAILURE);
026: }
027:
028: char tmp1[1000], tmp2[1000]; // array temporanei per lettura coppia
029:
030: // inizializzo array vuoto di "coppie", non basta il puntatore mna occorre anche un int che mi tiene traccia del numero di coppie lette
031: struct coppia *parole = NULL;
032: int ncoppie = 0;
033:
034: // leggo una riga sfruttando i due temporeanei, termino quando non riesco piu' a leggere niente
035: while(fscanf(fp, " %s %s", tmp1, tmp2) == 2)
036: {
037: // incremento il numero di coppie
038: ++ncoppie;
039: // "allargo" l'array dui struct per ospitare la nuova coppia di parole
040: parole = realloc(parole, sizeof(struct coppia)*ncoppie);
041: // per il nuovo elemento dell'array, alloco spazio a sufficienza nei due elementi per poter ospitare le due parole lette
042: parole[ncoppie - 1].parola1 = malloc(strlen(tmp1) + 1);
043: parole[ncoppie - 1].parola2 = malloc(strlen(tmp2) + 1);
044: // e ve le copio
045: strcpy(parole[ncoppie - 1].parola1, tmp1);
046: strcpy(parole[ncoppie - 1].parola2, tmp2);
047: }
048: fclose(fp);
049:
050: // scorro array di coppie
051: for(int i = 0; i < ncoppie; ++i)
052: {
053: printf("La coppia '%s' '%s' ", parole[i].parola1, parole[i].parola2);
054: // chiamo prima funzione e memorizzo valore restituito
055: int pal = check_palindromi(parole[i]);
056: // in base a valore stampo messaggio opportuno
057: if(pal == 2 )
058: printf("contiene 2 parole palindrome ");
059: else if(pal == 1)
060: printf("contiene 1 parola palindroma ");
061: else
062: printf("non contiene parole palindrome ");
063:
064: // come nel caso precedente per gli anagrammi
065: if(check_anagrammi(parole[i]))
066: printf("e sono anagrammi una dell'altra\n");
067: else
068: printf("\n");
069:
070: }
071:
072:
073:
074: return 0;
075: }
076:
077: // funzione ricorsiva che controlla se una singola stringa e' palindroma
078: // passo indirizzo stringa e lunghezza del numero di caratteri da controllare
079: int palindroma(char *parola, int lungh)
080: {
081: // se la stringa e' vuota o e' formata da un solo carattere la considero palindroma
082: if(lungh == 1 || lungh == 0)
083: return 1;
084:
085: // se il primo e l'ultimo carattere sono differenti non e' sicuramente palindroma
086: if(parola[0] != parola[lungh-1])
087: return 0;
088:
089: // richiamo funzione passando sottostringa che parte dal carattere successivo e un cui non considero anche l'ultimo carattere
090: return palindroma(parola + 1, lungh - 2);
091: }
092:
093:
094: // controllo palindromi sfruttando la funzione precedente
095: int check_palindromi(struct coppia c)
096: {
097: return palindroma(c.parola1, strlen(c.parola1)) + palindroma(c.parola2, strlen(c.parola2));
098: }
099:
100: // classica funzione necessaria per la qsort() gia' vista a lezione
101: int confronta_caratteri(const void *a, const void *b)
102: {
103: char ca = *((char *)a);
104: char cb = *((char *)b);
105:
106: return ca - cb;
107: }
108:
109: // se due parole sono anagrammi contengono le stesse identiche lettere solo distribuite
110: // diversamente
111: // questa funzione ordina i caratteri delle due stringhe in ordine alfabetico, se sono anagrammi una dell'altra
112: // otterro' due stringhe identiche
113: int check_anagrammi(struct coppia c)
114: {
115: // uso qsort per ordinare due stringhe ovvero due array di char
116: qsort(c.parola1, strlen(c.parola1), sizeof(char), confronta_caratteri);
117: qsort(c.parola2, strlen(c.parola2), sizeof(char), confronta_caratteri);
118: // controllo se dopol'ordinamento sono o meno identiche
119: if(!strcmp(c.parola1, c.parola2))
120: return 1;
121: else // a rigore non necessario ma comunque piu' chiaro
122: return 0;
123: }
124: