Обратная строка в 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, но я думаю, что это медленнее на большинстве платформ.