2013-04-14 32 views
5

Mi chiedo di sapere quale variante del programma è migliore di runtime?
Entrambe le varianti sono facili da implementare. Ma cosa è meglio usare e in quali casi?Quali varianti di stringa inversa sono migliori?

stringa inversa:

public static String reverse(String s) 
{ 
    String rev = ""; 
    for (int i = s.length() - 1; i >= 0; i--) 
     rev += s.charAt(i); 
    return rev; 
} 

StringBuilder contrario:

public static String reverse(String s) 
{ 
    StringBuilder rev = new StringBuilder(); 
    for (int i = s.length() - 1; i >= 0; i--) 
     rev.append(s.charAt(i)); 
    return rev.toString(); 
} 
+2

Quanto spesso hai bisogno di fare questo? Quanta differenza avrà l'attività se sceglierai un'opzione rispetto all'altra?Finché non puoi rispondere a queste domande, non hai molte basi per prendere una decisione. Tutto quello che puoi dire è che il secondo è più efficiente del primo, * se * hai una stringa più lunga di 1 carattere. –

+1

Secondo snippet meglio usare 'tempo lineare'. Prima usare il 'tempo quadratico'. –

risposta

6

nei tuoi due casi: io preferisco la seconda

perché il compiler will convert the first one from:

rev += s.charAt(i);

a:

(new StringBuilder()).append(rev).append(s.charAt(i)).toString();

Ma, see the worst case scenario:

public class Main 
{ 
    public static void main(String[] args) 
    { 
     long now = System.currentTimeMillis(); 
     slow(); 
     System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms"); 

     now = System.currentTimeMillis(); 
     fast(); 
     System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms"); 
    } 

    private static void fast() 
    { 
     StringBuilder s = new StringBuilder(); 
     for(int i=0;i<100000;i++) 
      s.append("*");  
    } 

    private static void slow() 
    { 
     String s = ""; 
     for(int i=0;i<100000;i++) 
      s+="*"; 
    } 
} 

l'uscita sarà:

slow elapsed 173 ms 
fast elapsed 1 ms 
+1

+1 per indicare la conversione del compilatore e fornire il codice di test del tempo (vorrei +2 se potessi! :) – acdcjunior

5

Nessuno dei due è davvero ottimo considerando che si può semplicemente fare:

new StringBuilder(str).reverse().toString(); 

Se doveva usare per usare uno dei precedenti, quindi scegliere il reverse StringBuilder - con il primo si poteva benissimo inviare il GC attraverso il tetto creando e smaltendo tutti gli oggetti stringa di cui si hanno i caratteri.

+3

L'uso di StringBuilder.reverse() è diverso: considera le coppie surrogate come un singolo carattere, mentre entrambi i snippet sopra non lo fanno. Quindi se le coppie surrogate devono essere considerate come un singolo carattere, l'uso di StringBuilder.reverse() è una buona idea. Altrimenti, se la prestazione è la preoccupazione principale, è probabilmente più lenta del secondo snippet. –

+0

@JBNizet Buon punto, mi ero dimenticato delle coppie surrogate. – berry120

0

String classe in Java è immutabile e non può cambiare nella sua vita, e la concatenazione di due stringhe creare nuove String e tornare, ma StringBuilder è una sequenza mutabile di caratteri che possono cambiare caratteri della stringa in memoria, e l'utilizzo di StringBuilder dovrebbe essere migliore.
come un'altra soluzione, è possibile convertire la stringa a char array e array di retromarcia e, infine, convertire in stringa

char[] arr = s.toCharArray(); 
char tmp; 
int maxIndex = arr.length-1; 
for(int i = arr.length>>2; i>=0;i--) { 
    tmp = arr[i]; 
    arr[i] = arr[maxIndex-i]; 
    arr[maxIndex-i] = tmp; 
} 
return new String(arr); 

per maggiori informazioni vedi javadoc: StringBuilder, String
e potete StringBuilder codici sorgente di classe per capire che vogliono è davvero capita su aggiungendo un carattere

0

Alcuni dettagli interessanti.
Possiamo scrivere una funzione ricorsiva per invertire una stringa e non utilizzare alcun loop. Utilizzare il metodo String substring():

public static String reverse(String s) { 
    int N = s.length(); 
    if (N <= 1) return s; 
    String a = s.substring(0, N/2); 
    String b = s.substring(N/2, N); 
    return reverse(b) + reverse(a); 
} 

Quanto è efficiente questo metodo?
Questo metodo ha un tempo di esecuzione linearithmic .

Problemi correlati