|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
Mi suggerite l'algoritmo? [Java]
Ciao a tutti. Sto scrivendo un programmino che memorizza in array una sequenza di numeri che vengono digitati dall'utente e successivamente devono essere stampati in ordine cardinale.
La grandezza dell'array viene definita dall'utente stesso all'inizio del programma... Io fino ad ora ho scritto questo che serve a memorizzare nell'array i numeri digitati: Codice:
//lettura for (pos = 1; pos < numeri.length; pos++) { int numero = in.readInt("Numero? "); numeri[pos] = numero; } per quanto riguarda la stampa a video ho semplicemente scritto questo: Codice:
//scrittura for ( pos = 1; pos < numeri.length; pos++){ out.println(numeri[pos]); } quello che ho provato a fare è questo, ma evidentemente non funziona ![]() Codice:
for (pos = 1; pos < numeri.length; pos++) { if (numeri[pos] > numeri[pos++]) numeri[pos] = numeri[pos++]; } ![]()
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Sep 2008
Messaggi: 237
|
Fatti un vettore copia e riempilo gia ordinato, che e' piu facile.
Comunque sono due for annidati, uno per riempire il vettore e uno per fare la scansione dei numeri inseriti dall'utente e scegliere quello con l'ordine giusto. Poi per ottimizzarlo ci sono tanti modi. |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Quote:
Comunque ricorda che: - Quando scrivi pos++, la variabile pos viene incrementata! quindi nella riga sotto quel pos è equivalente a "pos + 1"; - scrivendo numeri[pos] = numeri[pos++]; stai sovrascrivendo il valore contenuto in numeri[pos], e quest'ultimo che fai? lo perdi? Ciao ![]() |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Per ordinare un vettore puoi usare uno dei tanti algoritmi esistenti.
Ovviamente ognuno ha la sua complessità temporale che tipicamente varia tra O(n^2) e O(nLog(n)), esistono alcuni ordinamenti O(n) ma si possono usare solo in casi particolari. La complessità temporare da indicazione del tempo che impiega a ordinare: per ordinare 1000 valori un algoritmo O(n) impiega 1000 unità di tempo, un algoritmo O(n^2) impiega 1000000 unità di tempo. Lavorando con grandi quantitativi di dati questo si sente molto. Un algoritmo molto semplice è quello descritto da tacchinox, che prevede la selezione del più basso dal vettore e la copia in un nuovo vettore, e ha complessità O(n^2). Un altro algoritmo semplice potrebbe essere il selection sort, che non necessita di un altro vettore. Divide il vettore di partenza in una parte ordinata e una non ordinata e ad ogni ciclo sostituisce il primo valore della parte non ordinata con il valore più basso della stessa. Per esempio: 6 2 5 1 7 9 3 inizialmente tutto il vettore costituisce la parte non ordinata, la prima mossa è trovare il valore inferiore e metterlo al primo posto della sequenza non ordinata (inverto 1 con 6): 1 2 5 6 7 9 3 In verde è la sequenza ordinata. Ora cerco il minore tra i non ordinati: è 2 e si trova già al primo posto della parte non ordinata, quindi non faccio niente 1 2 5 6 7 9 3 Continuando trovo 3 e lo sostituisco con il 5 1 2 3 6 7 9 5 5 con il 6 1 2 3 5 7 9 6 e via dicendo... Ci sono algoritmi ben più raffinati e prestanti ma richiedono più attenzione (merge sort, quicksort...) su wikipedia ne trovi molti, con anche del pseudocodice se vuoi implementarli http://it.wikipedia.org/wiki/Categor...di_ordinamento ps: fai attenzione anche a quello che ha scritto Dan___88: è un errore comune copiare un valore al posto di uno già esistente senza tenersi una copia di quello che c'era prima (perdi il dato)
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight |
![]() |
![]() |
![]() |
#5 | |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
Quote:
senza andare troppo sul difficile, come posso implementare l'algoritmo descritto da te e tacchinox? creo un nuovo array copia del precedente (già ordinato), ma per ordinarlo... un altro ciclo for come quello che avevo già fatto? ![]()
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Un algoritmo semplice è questo:
Ti crei un vettore vuoto (stessa dimensione), Poi cicli n volte sul vettore, ad ogni ciclo trovi l'elemento più piccolo e lo pushi nel vettore copia (ovviamente devi ricordati quali numeri hai già preso, ad esempio se sono numeri positivi, puoi sostituire ogni elemento con -1 quando lo copi nel nuovo vettore |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Arrays.sort(numeri);
|
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
ok ho provato a implementare aggiungendo questa porzione di codice:
Codice:
int[] newArray = new int[MAX+1]; for (pos = 1; pos < numeri.length; pos++) { if (numeri[pos] > numeri[pos++]) numeri[pos] = newArray[pos]; } continuo a sbagliare su questo esercizio ![]() @Vegeta: devo risolvere attraverso una struttura dati, non mi serve una funzione del linguaggio ![]()
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... Ultima modifica di djadry : 02-01-2012 alle 15:33. |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
ovviamente non va bene,..
e poi stai mettendo dentro numeri[pos] il contenuto di newArray[pos].. che senso ha?? Il minimo (o massimo) di un array lo sai calcolare? Se non sai farlo, dovresti esercitarti prima su qualcosa di più semplice. Devi fare due cicli innestati (tu ne hai fatto solo uno..), nel primo ciclo scorri newArray, nel secondo trovi di volta in volta il minimo dell'array e lo metti dentro newArray (nella posizione data dall'indice del primo ciclo). |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Quote:
L'algoritmo che ri serve è molto semplice ma sarebbe didatticamente inutile se ti venisse proposto un algoritmo dal nulla da copia-incollare. Il mio consiglio è di buttare giù uno schema o uno pseudocodice che ti permetta di lavorare sulla logica dell'algoritmo prima della semantica da usare per applicarlo al Java. Posso però proporti alcune riflessioni e consigli: innanzi tutto il vettore... MAX suppongo sia il numero di valori massimo che deve contenere il vettore. perchè crei un array di dimensione MAX+1? cosa ti serve quel +1? se MAX è il numero di elementi che vuoi far contenere all'array, usa MAX da solo. E quando poi nel for accedi all'array, perchè parti con pos=1 e non pos=0? il primo elemento del vettore è numeri[0], non numeri[1]. Poi ancora, la condizione Codice:
if (numeri[pos] > numeri[pos++])
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight |
|
![]() |
![]() |
![]() |
#11 | ||
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
Quote:
Quote:
Codice:
int[] newArray = new int[MAX]; for (pos = 0; pos < newArray.length; pos++) { for (i = 0; i < newArray.length; i++) { if (numeri[pos] > newArray[i]) newArray[i] = numeri[pos]; } } for (i = 0; i < newArray.length; pos++) out.println(newArray[pos]);
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... Ultima modifica di djadry : 02-01-2012 alle 17:34. |
||
![]() |
![]() |
![]() |
#12 | |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
Quote:
grazie per le spiegazioni ![]()
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Intanto ragioniamo su come trovare il minimo di un array:
ci serve una variabile temporanea su cui memorizzare il minimo locale (la settiamo ad un valore sufficientemente grande): Codice:
int min = 9999999 Codice:
for (pos = 0; pos < numeri.length; pos++) { if (numeri[pos] < min) min = numeri[pos]; } Nel tuo caso, per ordinare devi fare così: Codice:
int min = 99999 for (int i = 0; i < newArray.length; i++) { for (pos = 0; pos < numeri.length; pos++) { if (numeri[pos] < min) min = numeri[pos]; numeri[pos] = 99999 // così al prossimo ciclo non verrà considerato } newArray[i] = min; } ![]() |
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
ok fino a qui ci sono. ho provato a stampare a video newArray[i] per vedere se effettivamente mi ha posizionato il minor valore in quella posizione, ma mi da un errore... ma non entriamo in merito perchè faccio già abbastanza casino...
ora devo confrontare gli elementi degli array. il metodo che avevo usato sopra funziona?
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Il codice che ho scritto nella parte finale
Codice:
int min = 99999 for (int i = 0; i < newArray.length; i++) { for (pos = 0; pos < numeri.length; pos++) { if (numeri[pos] < min) min = numeri[pos]; numeri[pos] = 99999 // così al prossimo ciclo non verrà considerato } newArray[i] = min; } Alla fine della sua esecuzione, newArray dovrebbe contenere i valori di numeri ordinati |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Quote:
![]() Fissare min a una costante, anche se grande, non è logicamente corretto. Innanzi tutto perchè anche se la costante è grande, non si sa se sia effettivamente maggiore di ogni elemento dell'array, se il numero più basso fosse 10000000, non funzionerebbe. Il numero "sicuro" da assegnare sarebbe il massimo previsto da int, e corrisponde alla costante Codice:
Integer.MAX_VALUE A questo punto, propongo anche una mia soluzione che ricalca l'algoritmo selection sort, che è quello che ho descritto qualche post sopra (consiglio vivamente di rileggere l'esempio pratico che ho fatto sopra, non ha senso copiare senza capirlo): Codice:
public static void selectionSort(int[] array){ int j, tmp, min = 0; //inizializzazione variabili, j e min sono indici, //tmp è una variabile temporanea per gli spostamenti for (int i = 0; i < array.length; i++){ //ciclo esterno, ripete n volte (n = dimensione array) for (j = min = i; j < array.length; j++) //ciclo interno, ripete n - i volte if (array[j] < array[min]) //Se l'elemento in indice j è inferiore a quello in indice min min = j; //allora min = j //le seguenti 3 istruzioni invertono il primo elemento non ordinato //con l'elemento minore della sottostringa non ordinata tmp = array[i]; //copio il primo elemento non ordinato in variabile temporanea array[i] = array[min]; //copio l'elemento minore al posto del primo elemento non ordinato array[min] = tmp; //copio l'elemento non ordinato precedentemente salvato //in tmp al posto dell'elemento minore trovato } } ![]() Consiglio anche una visitina a wikipedia per la descrizione teorica dell'algoritmo selection sort: http://it.wikipedia.org/wiki/Selection_sort
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight Ultima modifica di demos88 : 02-01-2012 alle 23:01. |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Quote:
innanzi tutto nel ciclo interno Codice:
if numeri[pos] < min Poi a ogni completamento del for interno, la variabile min andrebbe impostata nuovamente al valore grande, altrimenti riempi l'intero array con numeri tutti uguali (uguali al minore dell'array di partenza).
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
amico ti mancano proprio le basi
![]() |
![]() |
![]() |
![]() |
#19 |
Member
Iscritto dal: Dec 2009
Città: Varese
Messaggi: 274
|
non ci sto capendo più una cippa
![]() io ho riscritto tutto seguendo il consiglio di dan_88 ma evidentemente non funziona correttamente perchè mi stampa un unico valore. Codice:
int MAX = in.readInt("Quanti numeri vuoi inserire? "); //creo array int[] numeri = new int[MAX]; //ciclo for lettura for (int i = 0; i < numeri.length; i++) { int num = in.readInt("Numero? "); numeri[i] = num; } //creo nuovo array int[] nuovo = new int[MAX]; //trovo minimo dell'array int min = 99999; for (int h = 0; h < nuovo.length; h++) { for (int i = 0; i < numeri.length; i++) { if (numeri[i] < min) min = numeri[i]; numeri[i] = 99999; } nuovo[h] = min; out.println(nuovo[h]); }
__________________
![]() AMD Ryzen 1700X, ASUS Crosshair VI Hero, 32 GB DDR4 Corsair Vengeance 3200, NVidia GTX 960, Samsung 970 PRO, Phanteks Enthoo EVOLV ATX TG, LC EKWB custom loop e un po' di RGB... Ultima modifica di djadry : 04-01-2012 alle 15:56. |
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
facci sapere se hai bisogno
![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:40.