我有一个字符串,我想反转它。例如,我正在编写一个反转字符串的AngularDart过滤器。它仅用于演示目的,但它让我想知道如何反转字符串。
示例:
Hello, world
应该变成:
dlrow ,olleH
我还应该考虑使用unicode字符的字符串。例如:'Ame\u{301}lie'
什么是反转字符串的简单方法,即使它有?
答案 0 :(得分:37)
问题没有明确定义。反转任意字符串没有意义,将导致输出中断。第一个(可克服的)障碍是Utf-16。 Dart字符串被编码为Utf-16,并且仅反转代码单元导致无效字符串:
var input = "Music \u{1d11e} for the win"; // Music for the win
print(input.split('').reversed.join()); // niw eht rof
split
函数明确警告此问题(带示例):
使用空字符串模式('')拆分以UTF-16代码单元边界分割而不是符文边界[。]
有一个简单的解决方法:不是反转单个代码单元,而是可以反转符文:
var input = "Music \u{1d11e} for the win"; // Music for the win
print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof cisuM
但这不是全部。符文也可以有特定的顺序。第二个障碍是很多难以解决。一个简单的例子:
var input = 'Ame\u{301}lie'; // Amélie
print(new String.fromCharCodes(input.runes.toList().reversed)); // eiĺemA
请注意,重音是错误的字符。
可能还有其他语言对单个符文的顺序更为敏感。
如果输入有严格的限制(例如Ascii或Iso Latin 1),则技术上可以反转字符串。但是,我还没有看到这个操作有意义的单个用例。
使用这个问题作为示例,表明字符串具有类似List的操作也不是一个好主意。除少数用例外,必须根据特定语言处理字符串,并使用具有特定语言知识的高度复杂方法。
特别是母语为英语的人必须注意:字符串很少被处理,好像它们是单个字符列表一样。在几乎所有其他语言中,这将导致错误的程序。 (并且不要让我开始toLowerCase
和toUpperCase
...)。
答案 1 :(得分:9)
这是在Dart中反转 ASCII 字符串的一种方法:
input.split('').reversed.join('');
注意:这不一定是反转字符串的最快方法。查看替代品的其他答案。
注意:这不能正确处理所有unicode字符串。
答案 2 :(得分:4)
我为一些不同的选择做了一个小基准:
String reverse0(String s) {
return s.split('').reversed.join('');
}
String reverse1(String s) {
var sb = new StringBuffer();
for(var i = s.length - 1; i >= 0; --i) {
sb.write(s[i]);
}
return sb.toString();
}
String reverse2(String s) {
return new String.fromCharCodes(s.codeUnits.reversed);
}
String reverse3(String s) {
var sb = new StringBuffer();
for(var i = s.length - 1; i >= 0; --i) {
sb.writeCharCode(s.codeUnitAt(i));
}
return sb.toString();
}
String reverse4(String s) {
var sb = new StringBuffer();
var i = s.length - 1;
while (i >= 3) {
sb.writeCharCode(s.codeUnitAt(i-0));
sb.writeCharCode(s.codeUnitAt(i-1));
sb.writeCharCode(s.codeUnitAt(i-2));
sb.writeCharCode(s.codeUnitAt(i-3));
i -= 4;
}
while (i >= 0) {
sb.writeCharCode(s.codeUnitAt(i));
i -= 1;
}
return sb.toString();
}
String reverse5(String s) {
var length = s.length;
var charCodes = new List(length);
for(var index = 0; index < length; index++) {
charCodes[index] = s.codeUnitAt(length - index - 1);
}
return new String.fromCharCodes(charCodes);
}
main() {
var s = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
time('reverse0', () => reverse0(s));
time('reverse1', () => reverse1(s));
time('reverse2', () => reverse2(s));
time('reverse3', () => reverse3(s));
time('reverse4', () => reverse4(s));
time('reverse5', () => reverse5(s));
}
结果如下:
reverse0: => 331,394 ops/sec (3 us) stdev(0.01363)
reverse1: => 346,822 ops/sec (3 us) stdev(0.00885)
reverse2: => 490,821 ops/sec (2 us) stdev(0.0338)
reverse3: => 873,636 ops/sec (1 us) stdev(0.03972)
reverse4: => 893,953 ops/sec (1 us) stdev(0.04089)
reverse5: => 2,624,282 ops/sec (0 us) stdev(0.11828)
答案 3 :(得分:2)
尝试此功能
String reverse(String s) {
var chars = s.splitChars();
var len = s.length - 1;
var i = 0;
while (i < len) {
var tmp = chars[i];
chars[i] = chars[len];
chars[len] = tmp;
i++;
len--;
}
return Strings.concatAll(chars);
}
void main() {
var s = "Hello , world";
print(s);
print(reverse(s));
}
<强>(或)强>
String reverse(String s) {
StringBuffer sb=new StringBuffer();
for(int i=s.length-1;i>=0;i--) {
sb.add(s[i]);
}
return sb.toString();
}
main() {
print(reverse('Hello , world'));
}
答案 4 :(得分:0)
库More Dart包含一个围绕字符串的轻量级包装器,使它们表现得像一个不可变的字符列表:
import 'package:more/iterable.dart';
void main() {
print(string('Hello World').reversed.join());
}
答案 5 :(得分:0)
有一个utils软件包涵盖了此功能。它具有一些用于操作字符串的更出色的方法。
通过:
安装dependencies:
basic_utils: ^1.2.0
用法:
String reversed = StringUtils.reverse("helloworld");
Github:
答案 6 :(得分:0)
在Dart中有很多方法可以反向转换字符串,其中一些方法如下。
使用拆分和合并:
String reverseStringUsingSplit(String input) {
var chars = input.split('');
return chars.reversed.join();
}
使用符文:
String reverseStringUsingRunes(String input) {
var chars = input.runes.toList();
return String.fromCharCodes(chars.reversed);
}
使用代码单位:
String reverseStringUsingCodeUnits(String input) {
return String.fromCharCodes(input.codeUnits.reversed);
}
您可以简单地使用所有此类方法
void main() {
var coflutter = 'Coflutter';
print(reverseStringUsingSplit(coflutter));
print(reverseStringUsingRunes(coflutter));
print(reverseStringUsingCodeUnits(coflutter));
}
所有3种方法的输出均为
rettulfoC
rettulfoC
rettulfoC