Обратная строка в Haxe (2.10)

Какие есть другие варианты, чтобы изменить строку в Haxe? Я представляю мой (простой, понятный и как новичок):

class ReverseString {

    public static function main() {

        neko.Lib.print("Enter some words: ");
        // Lets read some input!
        var someWord = Sys.stdin().readLine();

        // Split string to array, reverse string, and join again
        var stringArray:Array<String> = someWord.split("");
        stringArray.reverse();
        var reversedString = stringArray.join("");

        // And finally, enjoy the reversed string:
        neko.Lib.print("Reversed word looks like this: ");
        neko.Lib.println(reversedString);
    }
}

2 ответа

Использование split () является медленным по сравнению с некоторыми другими методами, особенно если строка достаточно велика.

Приведенные ниже тесты выполняются на моем компьютере для цели Neko, скомпилированы с Haxe 2.10. Давайте сначала проверим 6-символьную строку ("abcdef").

Реализация A с split/join занимает около (0.030ms):

var s = "abcdef"; 
var a = s.split(''); 
a.reverse(); 
s = a.join('');

// s contains "fedcba"

Реализация B выполняется примерно одинаково медленно, если не медленнее, чем решение A (0,032 мс):

var s = "abcdef";
var s2 = ""; 
for (i in -s.length+1...1) 
    s2 += s.charAt(-i);

// s2 contains "fedcba"

Реализация C в 5 раз быстрее, чем реализация A (0,006 мс):

import StringBuf;
using StringTools;

var s = "abcdef"; 
var s2 = new StringBuf(); 
for (i in -s.length+1...1) 
     s2.add(s.charAt(-i)); 

// s2.toString() contains "fedcba"

Реализация D выглядит быстрее всего, примерно в 16 раз быстрее, чем реализация A (0,002 мс):

import StringBuf;
using StringTools;

var s = "abcdef"; 
var s2 = new StringBuf(); 
for (i in -s.length+1...1) 
     s2.addChar(s.fastCodeAt(-i)); 

// s2.toString() contains "fedcba"
// if introducing var s3 = s2.toString() it then takes from 0.003 to 0.004ms total
// so this still seems the fastest on Neko.

Результаты измерений в Neko с 6-символьной строкой (рассчитанной из 500 000 итераций и разделенной соответственно):

  • A: 0,030 мс
  • B: 0,032 мс (худшее)
  • C: 0,006 мс (в 5 раз быстрее, чем A)
  • D: 0,002 мс (лучше всего, в 16 раз быстрее, чем A)

Измерения строки из 250 символов (рассчитанные из 500 000 итераций и разделенные соответственно):

  • A: 0,996 мс
  • B: 1,326 мс (все еще хуже)
  • C: 0,166 мс (в 6 раз быстрее, чем A)
  • D: 0,044 мс (лучше всего, в 22 раза быстрее, чем A)

Результаты показывают, что реализация A становится медленнее и медленнее относительно D по мере увеличения размера строки (что означает, что ее функция сложности O(n) хуже).

По этим причинам я рекомендую реализацию D.

Вы можете переместить код в отдельную статическую функцию:

class StringUtil {
    static public function reverse(s:String):String {
        var a = s.split('');
        a.reverse();
        return a.join('');
    }
}

А затем сделайте это:

using StringUtil;

class ReverseString {

    public static function main() {

        neko.Lib.print("Enter some words: ");
        // Lets read some input!
        var someWord = Sys.stdin().readLine();

        // Just reverse it
        var reversedString = someWord.reverse();

        // And finally, enjoy the reversed string:
        neko.Lib.print("Reversed word looks like this: ");
        neko.Lib.println(reversedString);
    }
}

Делает комментарий довольно устаревшим, не так ли?

В качестве альтернативы вы можете перебирать символы String в обратном порядке и добавлять их в StringBuf, но я думаю, что это медленнее на большинстве платформ.

Другие вопросы по тегам