какой код более эффективен? - PullRequest
1 голос
/ 25 октября 2011

Какой из следующих способов является эффективным способом перевернуть слова в строке?

public String Reverse(StringTokenizer st){
    String[] words = new String[st.countTokens()];
    int i = 0;
    while(st.hasMoreTokens()){
       words[i] = st.nextToken();i++}

    for(int j = words.length-1;j--)
       output = words[j]+" ";}

OR

public String Reverse(StringTokenizer st, String output){        
    if(!st.hasMoreTokens()) return output;        
        output = st.nextToken()+" "+output;
        return Reverse(st, output);}       

public String ReverseMain(StringTokenizer st){       
    return Reverse(st, "");}

хотя первый способ кажется более читабельным и понятным, в нем есть две петли. Во втором методе я попытался сделать это хвостовой рекурсией. Но я не уверен, что Java оптимизирует хвостовой рекурсивный код.

Ответы [ 4 ]

2 голосов
/ 25 октября 2011

Вы можете сделать это всего за один цикл

public String Reverse(StringTokenizer st){
    int length = st.countTokens();
    String[] words = new String[length];
    int i = length - 1;
    while(i >= 0){
      words[i] = st.nextToken();i--}
}
2 голосов
/ 25 октября 2011

Но я не уверен, оптимизирует ли java хвостовой рекурсивный код.

Это не так.Или, по крайней мере, реализации Sun / Oracle Java этого не делают, вплоть до Java 7.

Ссылки:


Я не знаю, делает ли это одно решение быстрее, чемдругой.(Протестируйте это сами ... стараясь избегать стандартных ловушек для микропроцессорных тестов.)

Однако тот факт, что Java не реализует оптимизацию хвостового вызова, означает, что второе решение может исчерпать себя.места в стеке, если вы дадите ему строку с большим (достаточным) количеством слов.


Наконец, если вы ищете более эффективный способ реализовать это, есть умный способ, который использует простоa StringBuilder.

  1. Создайте StringBuilder из вашего ввода String
  2. Поменяйте местами символы в StringBuilder, используя reverse().
  3. Пройдите по StringBuilder, указав начальное и конечное смещение каждого слова.Для каждой пары смещений начала / конца поменяйте местами символы между смещениями.(Вы должны сделать это, используя цикл.)
  4. Превратить StringBuilder обратно в String.
0 голосов
/ 25 октября 2011

StringTokenizer не считается устаревшим, но если вы читаете текущий JavaDoc ...

StringTokenizer является устаревшим классом, который сохраняется по соображениям совместимости, хотя его использование не рекомендуется в новом коде.Всем, кто ищет эту функцию, рекомендуется использовать вместо этого метод split String или пакет java.util.regex.

String[] strArray = str.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = strArray.length() - 1; i >= 0; i--)
    sb.append(strArray[i]).append(" ");

String reversedWords = sb.substring(0, sb.length -1) // strip trailing space 
0 голосов
/ 25 октября 2011

Вы можете проверить результаты, рассчитав оба из них на большое количество результатов

например.Вы переворачиваете 100000000 строк и видите, сколько секунд это займет.Вы также можете сравнить начальные и конечные системные временные метки, чтобы получить точную разницу между двумя функциями.

...