Selezione Ordina Java e analisi

Aug 26 2020

Ho scritto un codice di ordinamento della selezione in java. Conosco il suo algoritmo molto elementare, ma dato che sto imparando, volevo il tuo contributo sulla qualità del codice. Dai un'occhiata al codice: package selection_sort;

import java.util.Scanner;

public class SelectionSort {

int [] arrayToBeSorted;
Scanner scan=new Scanner(System.in);


SelectionSort(){
    System.out.println("Enter the number of elements");
    int total=scan.nextInt();
    this.arrayToBeSorted=new int[total];
    for(int i=0;i<total;i++) {
        System.out.println("Enter the "+i+" number of elements");
        this.arrayToBeSorted[i]=scan.nextInt();
    }
    
}

public void Sort() {
    int minIndex,min;
    boolean swapRequired=false;
    for(int i=0;i<arrayToBeSorted.length;i++) {
        minIndex=i;
        min=this.arrayToBeSorted[i];
        for(int j=i+1;j<this.arrayToBeSorted.length;j++) {
            if(this.arrayToBeSorted[j]<min) {
                min=this.arrayToBeSorted[j];
                minIndex=j;
                swapRequired=true;
            }
        }
        if(swapRequired) {
            swap(i,minIndex);
        }
                    
    }
    
    for(int x:this.arrayToBeSorted) {
        System.out.print(x+" ");
    }
        
    }

public void swap(int i,int j) {
    
    //System.out.println("swap called, pos="+i+"and minindex="+j);
    int temp=this.arrayToBeSorted[i];
    this.arrayToBeSorted[i]=this.arrayToBeSorted[j];
    this.arrayToBeSorted[j]=temp;
    
    //System.out.println("------------");
    
}
public static void main(String[] args) {
    SelectionSort s=new SelectionSort();
    s.Sort();
}

}

Anche sull'analisi, poiché la selezione è O (n2), è perché sto usando il ciclo for nidificato. C'è qualche strumento che ci parli della complessità del codice? Grazie in anticipo e sii paziente se è molto ingenuo

Risposte

1 Bobby Aug 26 2020 at 23:37
int [] arrayToBeSorted;
Scanner scan=new Scanner(System.in);

Senza alcun modificatore, i membri e le funzioni sono package-private. Ciò significa che sono accessibili dallo stesso pacchetto, ma non da istanze che estendono la classe. Questa è una cosa estremamente strana, in realtà, quando la si guarda da un punto di vista orientato agli oggetti. Vuoi crearli privateo se le classi estese dovrebbero essere in grado di accedervi, protected.

Lo stesso vale per il costruttore.


    System.out.println("Enter the number of elements");
    int total=scan.nextInt();
    this.arrayToBeSorted=new int[total];

Potresti usare un List/ ArrayListinvece di un array, il che significherebbe che puoi ricevere tutti i numeri dagli utenti che vogliono senza dover specificare il conteggio in anticipo. Un input vuoto potrebbe essere utilizzato per dichiarare la fine dell'elenco. Tuttavia, questo ha lo svantaggio che devi usare Integeral posto di int, quindi è piuttosto difficile dire cosa sia meglio. Ha anche lo svantaggio che il rilevamento di un input vuoto è prontamente disponibile da Scanner, come dovresti usare nextLineper quello, con la conversione manuale in int.

Puoi anche emulare a Listaumentando dinamicamente l'array. O facendolo per ogni oggetto, le prestazioni non contano in questo caso d'uso, o raddoppiando le dimensioni quando necessario.


this.arrayToBeSorted=new int[total];

Hai bisogno del thismodificatore solo se hai una variabile con lo stesso nome nello stesso ambito, ad esempio in un costruttore:

public ValueContainer(int value) {
    this.value = value;
}

È pratica comune omettere thisse non necessario. Se ti trovi mai nella situazione in cui è confuso se viene utilizzata un'istanza, una variabile statica o locale, hai comunque fatto qualcosa di sbagliato.


for(int i=0;i<total;i++) {

Sono un sostenitore molto persistente dell'utilizzo di nomi "reali" per le variabili nei cicli.

for (int counter = 0; counter < total; counter++) {
// or
for (int index = 0; index < total; index++) {

public void Sort() {

Le convenzioni di denominazione Java stabiliscono che metodi/funzioni dovrebbero essere lowerCamelCase.


int minIndex,min;

Personalmente eviterei di dichiarare più variabili sulla stessa riga. Rende facile perdere la dichiarazione.


boolean swapRequired=false;

Questo è un ottimo esempio di un grande nome per una variabile, grazie!


    for(int x:this.arrayToBeSorted) {
        System.out.print(x+" ");
    }

Questo, sfortunatamente, è un brutto nome per una variabile. Usa solo "x", "y" e "z" quando lavori con le quote. "valore" o "numero" sarebbe un bel nome qui.


Nel complesso, sembra valido. Tuttavia, non l'ho eseguito per testare la funzionalità. Quello che dovresti cambiare è che hai la logica nel costruttore. Nessuno si aspetta che i costruttori siano pieni di logica, perché non puoi vedere l'intento della logica da loro. Dovrebbero essere il più possibile inattivi. Ciò significa che dovresti spostare la logica in sorto, meglio ancora, in main. Il tuo Sorter non dovrebbe preoccuparsi affatto dell'input, dovrebbe occuparsi solo dell'ordinamento dei valori, idealmente, e un'altra classe ( InputReader?) dovrebbe occuparsi di ottenere l'input. Quindi quello che potresti fare è qualcosa del genere:

public static final void main(String[] args) {
    InputReader inputReader = new InputReader();
    
    int[] values = inputReader.readValues();
    
    Sorter sorter = new Sorter();
    sorter.sort(value);
    
    // TODO Print sorted output.
}

Ciò ha anche il vantaggio che non è necessario mantenere lo stato Sorter, il che lo renderebbe thread-safe per impostazione predefinita.