反转字符串(也就是从右向左读,而不是从左向右读)是编程中一项出奇常见的任务。
例如,在生物信息学中,反转 DNA 或 RNA 字符串的序列往往对各类分析都很重要,比如寻找互补链,或者识别具有生物学意义的回文序列。
你的任务是反转给定的字符串。
一些示例:
"stressed"变成"desserts"。"strops"变成"sports"。"racecar"变成"racecar"。虽然字符串有#reversed和#reverseDo:这两个方法,但你能不能用更底层的字符迭代和流自己实现它呢?
为了帮你浏览代码,Pharo 有一个好用的代码查找工具。按 Shift-Enter 即可激活它。
注意:我们按照 Exercism 的惯例把解答命名为 ReverseString,不过更符合 Smalltalk 风格的名字应该是 StringReverser。
关于字符串,有一些小细节可能会让你在初次阅读时感到困惑,比如注释用双引号、字符串用单引号、字符有特殊语法(例如用 $x 表示字符“x”),因为这些约定和其他语言不同。
另外还有符号的概念,它是一种在整个内存中唯一的字符串;也就是说,当它被构造出来时(通常是在编译期),会先在内存中搜索,看是否已经存在一个相同的符号,最终只使用最初的那个。这样做不仅是为了节省内存,更重要的是在比较符号时能大幅提速。
"this is a comment"
'this is a string'
#'this is a symbol'
#thisIsASymbolToo
Smalltalk 程序里的逗号也非常少,因为逗号不承担任何语法作用。所以数组字面量里没有逗号,例如#(1 2 3 4 5)。不过,逗号本身也是一个运算符,在拼接两个字符串时你就会用到它,例如'string1', 'string2'。
最后,值得知道的是字符串和字符是不同的类。字符串是字符的集合。在遍历字符串时,这一点可能会让你措手不及,因为你可能会把字符传给一个期望字符串的方法。看看下面这个例子:
(('hello' at: 2) = $e) inspect.
(('hello' at: 2) = 'e') inspect.
流非常适合顺序读写。它省去了自增下标的麻烦,让代码更简洁。 流可以作用于任何集合。
stream := WriteStream on: String new.
stream nextPut: $h ; nextPutAll: 'ell' ; nextPut: $o.
stream contents inspect