【问题标题】:Parsing string in SmallTalk在 SmallTalk 中解析字符串
【发布时间】:2011-11-06 23:49:45
【问题描述】:

我正在尝试将字符串中的每个字符与下一个字符(a-> b、y -> z 等)进行切换。不知道如何在 Smalltalk 中做到这一点并尝试像这样组合:

x := 'costam'.
y := x asArray.
y do: [:charr | charr := charr + 1. ].
y do: [:char | Transcript show: char printString; cr].

我所做的是:遍历数组并增加每个字符.. 虽然它不起作用。我收到错误:尝试存储到参数中。我该如何解决这个问题并以正确的方式做到这一点?

现在我得到了这样的东西:

x := 'costam'.
y := x asArray.
b := y at: 2.


n := 1.
m := 5.

[ n < m ] whileTrue: [
n := n + 1.
y at: n put: 'a'.
Transcript show: (y printString).
].

剩下的问题是如何“增加”字符,例如 a -> b g -> h 等? 解决了

【问题讨论】:

  • 该解决方案当然只在 ascii 范围内有效。那里的字符的数字映射符合您的期望。如果您离开该范围,它将无法正常工作。好吧,它也不适用于 z,Z。您需要定义您“真正”想要做什么。你可以看到有一种习惯是通过构建派生类(收集:创建一个新字符串)而不是改变源结构(原始字符串)。

标签: string parsing smalltalk


【解决方案1】:

来自“Smalltalk-80”:

由于参数名称是伪变量名称,它们可以像变量名称一样用于访问值,但它们的值不能通过赋值来更改。在spend:for:的方法中,声明形式为

amount =: amount * taxRate

在语法上是非法的,因为无法重新分配 amount 的值。

您可以使用collect: 消息创建一个新集合:

z =: y collect: [:char | (ch asciiValue + 1) asCharacter ].

Characters 不回复+,因此您需要转换为Integer 并返回。请注意,由于Strings 是集合,它们也会响应collect:

x collect: [:ch | (ch asciiValue + 1) asCharacter ]

如果您只需要 ASCII 字符,则在转换回字符之前取余数模 128。

x collect: [:ch | (ch asciiValue + 1 \\ 128) asCharacter ]

如果您只想增加字母而不增加其他字符,请在块中添加条件。

x collect: [:ch | ch isLetter
                      ifTrue: [(ch asciiValue + 1) asCharacter]
                      ifFalse: [ch] ]

请注意,最后一个块不处理连续范围末尾的字母(例如$z,或者,如果解释器支持扩展 ASCII 或 Unicode,$&lt;16rD6&gt;),因为确切的方法取决于功能系统的(基本上,什么被认为是一个字母)。

【讨论】:

  • asciiValue 破坏了它,消息不理解 :(
  • @mish: 你确定要发送asciiValueCharacter 吗?你用的是什么翻译? asciiValueCharacter 的标准消息。您的口译员可能还支持asIntegervalue
【解决方案2】:

试试这个:

x := 'costam'
answer := (x asIntegerArray collect: [ :c | c + 1]) asString.
Transcript show: answer

【讨论】:

  • 我已经以某种方式解决了,谢谢你的答案也会用到:)。
猜你喜欢
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 2012-01-07
  • 2011-06-20
  • 2010-10-11
  • 2017-10-12
  • 2011-07-03
相关资源
最近更新 更多