2013-04-14 5 views
5

Мне интересно узнать, какой вариант программы - лучшее время исполнения?
Оба варианта выглядят легко реализуемыми. Но что лучше использовать и в каких случаях?Какие варианты строк лучше?

Строка реверс:

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

StringBuilder реверс:

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

Как часто вам нужно это делать? Какая разница в бизнесе, если вы выберете один вариант над другим?Пока вы не сможете ответить на эти вопросы, у вас нет большой основы для принятия решения. Все, что вы можете сказать, это второе, более эффективное, чем первое, * если * у вас есть строка длиной более 1 символа. –

+1

Второй фрагмент лучше использовать 'linear time'. Сначала используйте «квадратичное время». –

ответ

6

в ваших двух случаях: я предпочитаю второй один

потому что compiler will convert the first one from:

rev += s.charAt(i);

к:

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

Но, 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+="*"; 
    } 
} 

выход будет:

slow elapsed 173 ms 
fast elapsed 1 ms 
+1

+1 для указания преобразования компилятора и предоставления кода тестирования времени (я бы +2, если бы мог! :) – acdcjunior

5

Ни действительно большой учитывая, что вы можете просто сделать:

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

Если вы пришлось использовать один из выше, хотя и выбрать реверс StringBuilder - с первым, который вы могли бы отправить GC через крышу, создавая и удаляя столько строковых объектов, сколько у вас есть символы.

+3

Использование StringBuilder.reverse() отличается: он рассматривает суррогатные пары как один символ, тогда как оба вышеописанных фрагментов не делают. Поэтому, если суррогатные пары должны рассматриваться как один символ, использование StringBuilder.reverse() - хорошая идея. В противном случае, если производительность является основной проблемой, она, вероятно, медленнее второго фрагмента. –

+0

@ JBNizet Хорошая мысль, я забыл о суррогатных парах. – berry120

0

String класса в Java неизменена и не может изменить в своей жизни, и конкатенация два строки создать новую String и вернуться, но StringBuilder является изменяемой последовательностью символов, которая может изменить символы строки в памяти, и с помощью StringBuilder должен быть лучше.
в качестве другого решения, вы можете преобразовать строку в массив символов и обратный массив и, наконец, преобразовать в строку

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); 

для получения дополнительной информации см Javadoc: StringBuilder, String
и посмотреть StringBuilder источник класса коды понять хотите действительно происходят на добавление символа

0

Некоторые интересные детали.
Мы можем написать рекурсивную функцию для изменения строки и не использовать никаких циклов. Используйте метод Строка 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); 
} 

Насколько эффективен этот метод?
Этот метод имеет linearithmic время работы.

Смежные вопросы