Programma in linguaccio C

frenky46
Data una sequenza di caratteri alfabetici dire quante volte è presente in essa ciascuna lettera.

Questa è la traccia del programma, non riesco a capire come far cercare ciascuna lettera, avevo pensato di inserire diverse variabili ma ciascuna per il conteggio di ogni lettera dell'alfabeto utilizzando switch, però mi sembra un procedimento troppo lungo. C'è un modo più semplice e pratico per risolverlo?

Grazie :(

Risposte
apatriarca
Sì, c'è. Creare un array e usare il valore del carattere letto come indice in questo array.

frenky46
se ho capito bene chiamando con $x$ il carattere che viene letto dovrei creare un array del tipo $vet[x]$ giusto?
e poi come posso riconoscere ogni lettera?

apatriarca
Ad ogni lettera, per esempio 'a' corrisponde un codice numerico (che è quello che viene memorizzato nella variabile di tipo char). Puoi usare questo valore come indice all'interno di un array.

frenky46
:cry: Scusa potresti farmi un esempio perchè non riesco a capire :cry:

dzcosimo
creado che apatriarca intenda il codice ASCII
come probabilmente sai ogni cosa viene codificata sul calcolatore come sequenza di bit,ai bit concettualmente si associano valori numerici naturali, ai valori numerici naturali sempre concettualmente si associano numeri interi caratteri ecc
una delle possibili codifiche, la più usata insieme alla unicode, è la codifica ascii che associa ad ogni caratter un naturale e viceversa. Ed è proprio il naturale associato a quel carattere che viene restituito facendo un cast di una variabile, ad esempio:
char c='a'
int i=(int)c
cout< ouput:
97

come puoi vedere dalla tabbella che si trova qua:
http://en.wikipedia.org/wiki/ASCII

nel codice ascii le lettere ci fanno il favore di essere ordinate e dunque permettono ad esempio di farti usare un indice del tipo
x=(int)-97

Umby2
"frenky46":
:cry: Scusa potresti farmi un esempio perchè non riesco a capire :cry:


Se non vuoi utilizzare un metodo di "decodifica" del carattere, come ti è stato suggerito, potresti usare una tabella a 2 dimensioni (2 x 256).
La lunghezza 256 rappresentano i 256 caratteri possibili (maiuscole, minuscole, ed altri caratteri di interpunzione)
Nel primo campo ci metti il contenuto della lettera nel secondo la sua frequenza, man mano che trovi caratteri uguali.

Efficienza molto bassa, perchè dovrai ricercare di volta in volta il carattere nel vettore, e se non lo trovi lo posizioni al primo libero.
Potresti fare questa prova a titolo di esercitazione.

apatriarca
Non ha importanza la codifica utilizzata. 'a', 'b', ... 'z' sono valori numerici consecutivi e possono essere usati come indici per un array. Se quindi crei un array di 26 elementi, ognuno dei quali rappresenta una lettera, puoi usare i caratteri per accedere agli elementi dell'array. Se quindi c è la variabile con memorizzata la lettera che vuoi inserire e vec è l'array, ++vec[c - 'a'] incrementa il contatore per la lettera interessata e vec['c' - 'a'] è ad esempio il contatore per la lettera 'c'. Se non ci sono solo lettere minuscole ma anche altri caratteri si può aumentare la dimensione dell'array (usando per esempio un array di 256 elementi è sufficiente scrivere vec[c]) oppure seguire altre strade (per esempio convertire le lettere maiuscole in minuscole o ignorare i caratteri diversi o ...).

frenky46
:!: Vi ringrazio per le tante risposte anche se non vi nascondo che non riesco a capirci molto.
Comunque rileggendo bene la traccia ho notato che il programma richiede solo di contare quante volte è presente ciascuna lettera della sequenza e non ciascuna lettera dell'alfabeto.
Vi posto quello che sono riuscito a fare io :

#include
main()
{
char a[10] ;
int i , volte ;
volte=1;
printf("inserire la sequenza di caratteri\n");
for(i=0; i<10; i++)
{
scanf("%c", &a);
}
for(i=0; i<10; i++)
{
for(k=i+1; k<10; k++)
{
if(a==a[k])
{
volte=volte+1;
}
}
printf("il carattere %c è presente %d volte\n", a , volte);
}
}

Purtroppo ci sono diversi errori che non riesco a risolvere uno su tutti è che invece di 10 caratteri della sequenza me ne fa inserire solo 5. Qualcuno può darmi una mano? :?

Riuzaki
una soluzione potrebbe essere creare un array in cui inserire le lettere dell'alfabeto e con il quale fare i confronti con le lettere della stringa ad una ad una, poi crei un secondo array inizializzato a zero che avra lo stesso numero di elementi del primo array.
lo scopo è quello utilizzare l'indice dell'elemento della lettera trovata nel corrispondente elemento dell'array in cui salvi quante volte quella lettera è contenuta...alla fine stampi i valori del secondo array in relazione al primo ed hai risolto XD

Umby2
Non mi piace molto come algoritmo.
Se ad esempio dai in input la stringa "DIZIONARIO"
quando valuti la lettera "D" hai una ripetizione
poi la lettera I - 3 ripetizioni (ma successivamente incontrerai la seconda "I" e poi la terza e man mano avrai la frequenza diminuire)

Io dicevo di generare un vettore a 2 dimensioni che alla fine del conteggio ti dia:

DIZONAR
1312111

Riuzaki
ma è uguale a quello che dicevo io, o bidimensionale o due array è la stessa cosa. ovviamente il risultato è quello che dici tu. Ogni lettera che incontra cerca la posiziona adatta ed incrementa di uno il contatore corrispondente alla posizione ;)
CIAO
 A  B  C  D  E  F  G  H  I  L  M  N  O  P  Q  R  S  T  U  V  Z 
|0| 0| 0| 0 |0 |0| 0| 0| 0| 0|0| 0| 0| 0| 0 |0| 0| 0| 0| 0| 0|

DOPO IL PRIMO CONTROLLO:

 A  B  C  D  E  F  G  H  I  L  M  N  O  P  Q  R  S  T  U  V  Z 
|0| 0| 1| 0 |0 |0| 0| 0| 0| 0|0| 0| 0| 0| 0 |0| 0| 0| 0| 0| 0|

SECONDO CONTROLLO:

 A  B  C  D  E  F  G  H  I  L  M  N  O  P  Q  R  S  T  U  V  Z 
|0| 0| 1| 0 |0 |0| 0| 0| 1| 0|0| 0| 1| 0| 0 |0| 0| 0| 0| 0| 0|

TERZO:

 A  B  C  D  E  F  G  H  I  L  M  N  O  P  Q  R  S  T  U  V  Z 
|1| 0| 1| 0 |0 |0| 0| 0| 1| 0|0| 0| 0| 0| 0 |0| 0| 0| 0| 0| 0|

ULTIMO PASSAGGIO:

 A  B  C  D  E  F  G  H  I  L  M  N  O  P  Q  R  S  T  U  V  Z 
|1| 0| 1| 0 |0 |0| 0| 0| 1| 0|0| 0| 0| 0| 0 |0| 0| 0| 0| 0| 0|


alla fine stampi solo sode il valore dell'elemento è diverso da zero è cosi avrai quante volte è contenuta una, quante un'altra e via dicendo...

Umby2
"Riuzaki":
ma è uguale a quello che dicevo io,



il mio messaggio non era rivolto a te. :shock:
mentre scrivevo, tu hai inserito il tuo topic... sorry. :wink:

Riuzaki
capito...succede, tranquillo...XD

giozh
allora, vediamo se ho capito, tu prendi una stringa in input e devi restituire, per ogni lettera quante volte è contenuta in quella stringa no? premetto che conosco poco il c, ma grossomodo l'algoritmo generico è lo stesso. per comodità metti la stringa dentro un array di char e inizializzi una variabile intera (che conterrà il tuo risultato) a 1. poi fai due for, uno esterno e uno interno che invece ti servirà per contare quante volte il carattere puntato dal for esterno è presente nell'array. appena trovi un carattere uguale metti un flag null che ti indica che quel carattere già è stato contato e letto (per non contare piu volte caratteri uguali). ti faccio un esempio pratico. prendi in input la parola ciccio. il tuo array di char sarà [c,i,c,c,i,o] e inizializzi la tua variabile int res=1;
i due for saranno: for(i=0; i.equals(array[j] && array[j]!=null && array!=null) incrementi la tua variabile. alla fine del for interno avrai contato quante volte appare la lettera iesima, quindi stampi il risultato, resetti la variabile res ad 1. quindi dopo la prima scansione di ciccio avrai nell'array [c,i,null,null,i,o] (il primo carattere non è necessario metterlo a null, perche tanto nei cicli successivi non viene preso in considerazione. è chiaro o non c'hai capito nada?

frenky46
Non so se avete letto il mio post precedente, ma in pratica c'è stato un errore nell'interpretare la traccia.
L'esercizio è molto più semplice, devo solo dire quante volte è presente ciascuna lettera della sequenza, vi faccio un esempio :

Se io immetto come sequenza la seguente :
a
g
v
r
f
h
e
a
a
a

il programma deve dirmi :

la lettera a è presente 4 volte
la lettera g è presente 1 volte
la lettera v è presente 1 volte
la lettera r è presente 1 volte
la lettera f è presente 1 volte
la lettera h è presente 1 volte
la lettera e è presente 1 volte

Ho gia postato nel post precedente quello che sono riuscito a fare, ma ho dei problemi uno su tutti che non mi fa inserire 10 valori ma solo 5. Qualcuno può aiutarmi?

apatriarca
Se mostri tutto il codice che hai scritto forse possiamo capire come mai il tuo codice non funziona. Considera comunque che tutti i metodi che sono stati presentati nel post finora sono in grado di risolvere il tuo esercizio. Per ottenere la tua risposta dalla frequenza di tutte le lettere è infatti sufficiente estrarre quelle non nulle.

Riuzaki
te l' ho fatto nel modo più semplice possibile, spero di esserti stato di aiuto XD:

#include <iostream>

using namespace std;

const int Max = 21;

int conta_lettere(char lettera, int A[]);

char Alfabeto[Max] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'z'};

int main()
{
    char lettera;
    
    cout << "inserisci la tua frase e terminala con un punto: \n";
    
    cin >> lettera;
    
    int A[Max] = {0};
    
   while(lettera != '.')
   {
        if(lettera != ' ')    
           conta_lettere(lettera, A);     
         cin >> lettera;        
   }
   cout << "nella frase sono contenute:\n";
   for(int i = 0; i < 21; i++)
     {
           if(A[i] != 0)
             cout << A[i] << "   " << Alfabeto[i] << endl;
     }
     
   system("pause");
   return 0;
}

int conta_lettere(char lettera, int A[])
{
      for(int i = 0; i < 21; i++)
      {
            if(lettera == Alfabeto[i])  
               A[i]++;
      }
      return 0;
}

frenky46
"giozh":
allora, vediamo se ho capito, tu prendi una stringa in input e devi restituire, per ogni lettera quante volte è contenuta in quella stringa no? premetto che conosco poco il c, ma grossomodo l'algoritmo generico è lo stesso. per comodità metti la stringa dentro un array di char e inizializzi una variabile intera (che conterrà il tuo risultato) a 1. poi fai due for, uno esterno e uno interno che invece ti servirà per contare quante volte il carattere puntato dal for esterno è presente nell'array. appena trovi un carattere uguale metti un flag null che ti indica che quel carattere già è stato contato e letto (per non contare piu volte caratteri uguali). ti faccio un esempio pratico. prendi in input la parola ciccio. il tuo array di char sarà [c,i,c,c,i,o] e inizializzi la tua variabile int res=1;
i due for saranno: for(i=0; i.equals(array[j] && array[j]!=null && array!=null) incrementi la tua variabile. alla fine del for interno avrai contato quante volte appare la lettera iesima, quindi stampi il risultato, resetti la variabile res ad 1. quindi dopo la prima scansione di ciccio avrai nell'array [c,i,null,null,i,o] (il primo carattere non è necessario metterlo a null, perche tanto nei cicli successivi non viene preso in considerazione. è chiaro o non c'hai capito nada?


SI credo di aver capito, l'unico problema è nell ' if che forse c'è qualche errore di parentesi, comunque ora provo a risolverlo e vedo.

Riuzaki
il tuo ragionamento l'ho capito, ma è a parer mio molto contorto, infatti ogni volta ricontrolla tutte le lettere già controllate precedetemente e direi inutilmente. Prova a ragionare diversamente, cercando di fare un algoritmo che segua una logica migliore XD

Riuzaki
il tuo ragionamento l'ho capito, ma è a parer mio molto contorto, infatti ogni volta ricontrolla tutte le lettere già controllate precedetemente e direi inutilmente. Prova a ragionare diversamente, cercando di fare un algoritmo che segua una logica migliore XD

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.