DOMANDA Esercio vettori in C,Eliminazione dei duplicati

Pubblicità

Deadlift

Utente Attivo
Messaggi
903
Reazioni
1
Punteggio
47
Ciao ragazzi ,molto gentilmente, mi potreste dare un’occhiata a questo esercizio?Sono alle prime armi con gli array, e purtroppo per ora sono autodidatta e ho sempre paura di fraintendere il testo dell’esercizio. Penso di averlo fatto bene…ma non ne sono sicuro al 100%!


Utilizzate un vettore unidimensionale per risolvere il seguente problema.Leggete in input 20 numeri ,ognuno dei quali sarà compreso tra 10 e 100,estremi inclusi .Ogni volta che leggete un numero visualizzatelo qualora non sia un duplicato di uno già letto.Preparatevi al “caso peggiore” in cui tutti i 20 numeri siano differenti.Utilizzate il vettore più piccolo possibile per risolvere questo problema.

Quello che ho fatto io :

#include<stdio.h>
#define SIZE 20

int main(void)
{
int a[SIZE];
int i,min=10,max=90;
int freq[90]={0};



printf("Inserisci 20 numeri tra 10 e 100 \n");

printf("%s%13s","Input","Output\n\n");

for(i=0;i<SIZE;i++){/*immagazzina i numeri digitati nel vettore a,Fino a 20 numeri*/

scanf("%d",&a);

if(a<10 || a>90){/*i numeri devono essere compresi tra 10 e 90 ,se viene inserito un numero non compreso tra questi si genererà un errore*/

printf("Error\n");

break;}

++freq[a];/*tiene conto della frequenza dei numeri digitati dall'utente*/

if(freq[a] <2){/*se un numero viene ripetuto non viene visualizzato nell'output*/

printf("%13d\n",a);}}


return 0;
}
 

Allegati

  • vet.webp
    vet.webp
    106.9 KB · Visualizzazioni: 202
Codice:
if(a[i]<10 || a[i]>90)

i valori estremi dovrebbero essere 10 100, se i numeri da inserire devono essere compresi tra 10 e 100, così accetta solo i numeri tra 10 e 90.
 
Codice:
if(a[i]<10 || a[i]>90)

i valori estremi dovrebbero essere 10 100, se i numeri da inserire devono essere compresi tra 10 e 100, così accetta solo i numeri tra 10 e 90.

Ops!Non me n'ero accorto,grazie per avermi segnalato l'errore :) .Per il resto come va?
 
se scrivi if(a<10 || a>90), nel caso in cui a == 1000 la condizione sarebbe comunque verificata, perchè gli dici che deve essere una delle due, e infatti 1000 e più grande di 10, per farlo funzionare bene devi scrivere if(a<10 && a>90)

il resto del codice funziona bene, non sono esperto di c, programmo in altri linguaggi, però personalmente avrei preferito
Codice:
if(a[i]>=10 && a[i]<=90)
inserisci nella lista 

else
  errore


ciao
 
Grazie ancora crisi :) .Però secondo me non è cosi,perchè l'if vale per i numeri o <10 o maggiori di 90(sarebbe di 100) ,quindi se io scrivo 1000 mi da errore dal momento che 1000 è maggiore di 90.Guarda:
 

Allegati

  • if.webp
    if.webp
    135.1 KB · Visualizzazioni: 240
Ciao, non ho capito solo una cosa, perché usi 2 vettori?
Se ci pensi te ne basta uno :)
Tu devi semplicemente ricordarti i numeri che l'utente inserisce, quindi se crei un vettore con dimensione 91 (i numeri vanno da 10 a 100 inclusi, quindi sono 91 non 90 :)) a ogni posizione puoi assegnare un numero.
Provo a spiegarlo in maniera semplice: hai un vettore di 91 posizioni, da i=0 a i=90, quindi se l'utente deve inserire numeri compresi tra 10 e 100, alla posizione i+costante corrisponderà il relativo numero (dove costante=10); detto in altri termini, se l'utente inserisce un numero, chiamiamolo n, allora n-costante=posizione corrisponderà ad una ed una sola cella del vettore; se posizione non ricade tra gli estremi dell'intervallo [0,90] allora l'utente avrà inserito un numero non previsto, e lì puoi segnalare errore :)
Se l'utente inserisce un numero che da come posizione interna a [0,90] allora avrai un numero previsto. A questo punto ti basterà valutare il valore della cella del vettore; se ad esempio supponiamo di aver inizializzato tutte le celle del vettore a 0, se la posizione considerata è 0 significa che non hai ancora inserito il numero considerato, quindi puoi aumentare il valore della cella di 1; al contrario, se il valore della cella non è 0 significa che hai già considerato quel numero quindi puoi stamparlo sullo std output (volendo puoi aumentare quella posizione per valutare la frequenza con cui hai visualizzato quel numero) :)

Btw questo è un consiglio che ti do semplicemente per ottimizzare un po' il programma, volendo funziona anche come lo hai scritto tu (se non ho avuto delle sviste, a parte la dimensione di a che non è 90, ma 91) :)

- - - Updated - - -

Per farti un esempio, se non riesci a fare quello che ho scritto sopra puoi guardare lo spoiler qua sotto :)
Codice:
#include <stdio.h>


#define N 20        // numero degli elementi che devi inserire
#define CONST 10    // constante di addizione, ti serve per considerare elemnti che non partono da 0, ma da 10
#define SIZE 91        // dimensione del vettore


main(){
    int vett[SIZE]={0},i,n;    // inizializzo il vettore e dichiaro l'indice del ciclo for e la variabile in cui salvare i numeri passati dall'utente
    
    for(i=0;i<N;i++){        // inizio ciclo
    
        printf("Inserisci l'elemento %d: ",i);    // richiedo di passarmi l'elemento
        scanf("%d",&n);                            // lo salvo in n
        
        if( (n-CONST)<0 || (n-CONST)>90 ){        // controllo la validità dell'elemento inserito
            printf("Error\n");
            break;
        }
        
        if( vett[n-CONST]!=0 ) printf("Elemnto già inserito: %d\n",vett[n-CONST]);        // controllo se l'elemento era già stato inserito; stampa quanti numeri uguali ho già inserito prima
        
        ++vett[n-CONST];    // aumento il numero di volte in cui l'utente mi ha passato quell'elemento
        
    }
}
Se vuoi visualizzare il numero e non la frequenza con cui è stato inserito puoi stampare n oppure i+CONST :)
 
Ultima modifica:
Grazie Matteo per la risposta,in effetti hai ragione, il testo stesso dell'esercizio richiede di usare un vettore.Ritornerò su quell'esercizio però quando capirò quest'altro di cui il testo non mi è completamente chiaro.
(Totale delle vendite) Utilizzate una matrice per risolvere il seguente problema.Un'azienda ha quatro venditori(numerati da 1 a 4),che vendono cinque differenti prodotti(numerati da 1 a 5).Una volta al giorno,ognuno dei venditori forinisce un tagliando per ogni tipo di prodotto venduto.Ogni tagliando contiene:
1 il numero del venditore
2il numero del prodotto
3 il valore totale,espresso in dollari,del venduto giornaliero di quel prodotto.

Di conseguenza ,ogni venditore fornisce tra 0 e 5 tagliandi al giorno. Supponete che siano disponibili i dati dei tagliandi dell'ultimo mese.Scrivete un programma che legga le suddette informazioni,riguardanti il venduto dell'ultimo mese,e sommi le vendite totali per venditore e per prodotto.Tutti i totali dovranno essere immaggazinati nella matrice sales.Dopo aver elaborato tutte le informazioni dell'ultimo mese,visualizzate i risultati in formato tabulare in modo che le colonne rappresentino i vari venditori e le righe rappresentino i singoli prodotti. Sommate ogni riga ,in modo da ottenere le vendite totali dell'ultimo mese per ognuno dei prodotti;sommate ogni colonna,in modo da ottenere il totale delle vendite dell'ultimo mese per ognuno dei venditori.La vostra stampa tabulare dovrà includere i suddetti totali a destra delle righe e in fondo alle colonne.

Da quello che ho capito io la matrice deve essere 4*5, e io devo far corrispondere a ciascun elemento i esimo j esimo un valore arbitrario che rappresenti il totale delle vendite di quel prodtto per il rispettivo venditore.Io ho fatto cosi:

#include<stdio.h>
#define PRODOTTI 5
#define VENDITORI 4
void printarray(const int vendite[VENDITORI][PRODOTTI],int prod,int vend);
int main()
{
int sales[VENDITORI][PRODOTTI]=
{{6,4,2,1,3},
{6,4,2,1,3},
{6,4,2,1,3},
{6,4,2,1,3},
};
int riga,colonna,total=0;

printf("Totale delle vendite \n");
printarray(sales,PRODOTTI,VENDITORI);


return 0;}

void printarray(const int vendite[VENDITORI][PRODOTTI],int prod,int vend)
{
int i;/*contatore prod*/
int j;/*contatore vend*/

int t=0,t1=0,t2=0,t3=0,t4=0;
int t0=0,t5=0,t6=0,t7=0;

printf(" [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ]");

for(i=0;i<vend;i++){

printf("\n Venditore[%d]",i);
t+=vendite[0];
t1+=vendite[1];
t2+=vendite[2];
t3+=vendite[3];
t4+=vendite[4];
for(j=0;j<prod;j++){
printf("%-3d ", vendite[j]);
t0=vendite[0][0]+vendite[0][1]+vendite[0][2]+vendite[0][3]+vendite[0][4];
t5=vendite[1][0]+vendite[1][1]+vendite[1][2]+vendite[1][3]+vendite[1][4];
t6=vendite[2][0]+vendite[2][1]+vendite[2][2]+vendite[2][3]+vendite[2][4];
t7=vendite[3][0]+vendite[3][1]+vendite[3][2]+vendite[3][3]+vendite[3][4];







}
printf("%d",t0,t5,t6,t7);

}


printf("\n\n\n %13d%6d%5d%6d%6d ",t,t1,t2,t3,t4);
}




Inoltre non mi è chiaro nel testo dell'esercizio cosa voglia dire immaggazzinare i totali nella matrice sales e non riesco a capire perchè non mi venga questo :
t+=vendite[0];
t1+=vendite[1];
t2+=vendite[2];
t3+=vendite[3];
t4+=vendite[4];
con il contatore delle colonne ,infatti sono dovuto ricorrere alla somma dei singoli elementi.
Grazie mille per la pazienza!
 

Allegati

  • vendite.webp
    vendite.webp
    109.4 KB · Visualizzazioni: 197
Ultima modifica:
Provo a darti una mano :)

Dunque, partendo dall'esercizio tu sai di avere 4 prodotti che sono tutti venduti da più venditori, in particolare 5. Ora potresti pensare di schematizzarlo in forma tabellare, quindi se supponiamo di avere sulle righe i prodotti e sulle colonne i venditori avremo:
[TABLE="class: grid, width: 500"]
[TR]
[TD][/TD]
[TD]V_1[/TD]
[TD]V_2[/TD]
[TD]V_3[/TD]
[TD]V_4[/TD]
[TD]V_5[/TD]
[/TR]
[TR]
[TD]P_1[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_2[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_3[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_4[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[/TABLE]

La tua matrice non sarà altro che l'interno della tabella (ovvero le celle formate dalle combinazioni di P_X con V_Y) :)
Dato che il testo non ne fa menzione potresti anche pensare che i venditori vendano i prodotti allo stesso prezzo, quindi puoi definire i loro valori o come costanti (const) o con delle define.
A questo punto, se la tua matrice è carica non ti resta che svolgere le operazioni richieste; il testo ti dice di salvare i risultati all'interno della matrice, ma la cosa a mio avviso è abb brutta per una serie di motivazioni:
1) in termini di significato: abbiamo creato la matrice per inserire quantitativi di elementi e non prezzi, quindi la cosa a mio avviso stona un po';
2) problemi derivanti dai tipi: il problema è che le quantità sono degli interi (a meno che non parliamo di roba tipo chili di prosciutto ecc...), ma i prezzi possono essere tranquillamente numeri con la virgola, e questo in una matrice di interi non si può fare.

Diciamo che per attenerti all'esercizio potresti semplicemente aggiungere una riga ed una colonna alla matrice (che lascerai libere per calcolare i relativi totali); ora però bisogna risolvere i punti di sopra.
Il primo è più una questione interpretativa; essendo questo un esercizio potresti anche fregartene del primo punto, ma secondo me rendere il codice un po' più leggibile ti può facilitare la vita dopo.
Per il secondo punto, puoi risolverla imponendo che la matrice non sia di interi, ma di numeri con la virgola; sorge però un altro problema, ovvero l'utente può inserire quantità con la virgola senza controllo (pensa se mi compra qualcosa tipo 1,3 ventilatori :D); una soluzione è quella di imporre un controllo sul resto della divisione per 1 sui primi elementi di riga e colonna; i.e. puoi inserire la scanf che deve dare l'utente all'interno di un while:
Codice:
while( scanf("%f",matt[i,j])%1!=0 ) printf("Valore errato, ridigita\n");
Considerando però che la matrice è pre-caricata potresti anche sorvolare su questo punto, ma se ti fidi, più controlli fai, più sarai abituato a farli anche in programmi più complessi, e lì dovrai testarli veramente bene :)

Una volta che la matrice è carica basta che fai delle semplici somme. Solitamente l'approccio a questo tipo di strutture dati, quando le si vuole visionare completamente, è dato da 2 cicli for annidati, uno esterno che scorre le righe ed uno interno che scorre gli elementi per ogni riga (il motivo per cui non si fa l'opposto risiede nel come queste strutture sono memorizzate in memoria).
In questo caso si può sfruttare lo stesso procedimento con un po' di astuzia, ovvero considerando una matrice in cui gli elementi facenti parte dell'ultima riga e dell'ultima colonna siano inizializzati a 0:
Codice:
int i,J;    // dichiaro le variabili dei due cicli


for(i=0; i<RIG-1; i++){        // ciclo esterno che cicla le righe


    for(j=0; i<COL-1; i++){        // ciclo interno che cicla le colonne
    
        /* la cella che stiamo considerando influisce sia sul totale di riga che su quello di colonna */
        
        matt[i,COL-1] += matt[i,j];        // aggiungo il valore al totale di riga
        matt[RIG-1,j] += matt[i,j];        // aggiungo il valore al totale di colonna
    
    }    //end for interno


}    // end for esterno
NOTA BENE: in questo caso nella matrice che vai a creare devi moltiplicare ogni valore interno per il relativo costo prima dei sopra-citati cicli, altrimenti non sarai più in grado di distinguerli dopo. Questo tipo di operazione ti conviene farla nel momento in cui l'utente digita i valori che immetterai nella struttura dati (attraverso le costanti di cui ti parlavo all'inizio), in questo modo il tutto assumerebbe anche un significato più chiaro, ovvero avresti una matrice di soli prezzi (però perderesti l'informazione relativa alle quantità dei prodotti venduti per venditori, pur essendo derivabile).

Quindi la matrice risultante sarà l'interno della seguente tabella:
[TABLE="class: grid, width: 500"]
[TR]
[TD][/TD]
[TD]V_1[/TD]
[TD]V_2[/TD]
[TD]V_3[/TD]
[TD]V_4[/TD]
[TD]V_5[/TD]
[TD]TOT[/TD]
[/TR]
[TR]
[TD]P_1[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_2[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_3[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]P_4[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[/TR]
[TR]
[TD]TOT[/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD][/TD]
[TD]NULL[/TD]
[/TR]
[/TABLE]

Come puoi notare sorgerebbe anche un altro problema (seppur di poco conto): l'ultima cella non viene usata (volendo potresti fare il totale complessivo, ma imho è abb inutile).

Questo è più o meno quello che farei io per non sviare dal testo dell'esercizio :)
Tuttavia per rendere il tutto un po' più comprensibile preferirei inserire i totali in 2 vettori piuttosto che nella matrice stessa.

Venendo al codice:
void printarray(const int vendite[VENDITORI][PRODOTTI],int prod,int vend);
La dichiarazione del metodo non mi piace moltissimo, ovvero tu nel main dichiari già la dimensione della matrice; qua è meglio dichiarare il metodo in questo modo:
Codice:
void printarray(int venditore[][],int prod,int vend);
Il resto dipende da come hai inteso il problema; prova a vedere se con la spiegazione di sopra riesci a farlo funzionare :)

Spero di essermi riuscito a spiegare in maniera comprensibile :D
Ciao,
Matteo.
 
Grazie Matteo sei gentilissimo!Adesso mi rileggo tutto per bene poi ti so dire meglio :) .Piccola curiosità , ma sei del 91?
 
Grazie Matteo sei gentilissimo!Adesso mi rileggo tutto per bene poi ti so dire meglio :) .Piccola curiosità , ma sei del 91?
Si :)
Mi sono accorto di un errore che ho fatto:
Codice:
while( scanf("%f",matt[i,j])%1!=0 ) printf("Valore errato, ridigita\n");
Il codice corretto sarebbe:
Codice:
scanf("%f",matt[i,j]);

while( matt[i,j]%1!=0 ){

     printf("Valore errato, ridigita\n");
     scanf("%f",matt[i,j]);

}
Mi sono sbagliato a testare direttamente il ritorno della scanf, in realtà quello che intendevo era testare il valore inserito dall'utente :D
 
Pubblicità
Pubblicità
Indietro
Top