【问题标题】:How can I generate random integers in a range in Smalltalk?如何在 Smalltalk 中生成一个范围内的随机整数?
【发布时间】:2008-11-07 06:44:33
【问题描述】:

我目前正在学习的一门课程要求我们在 smalltalk 中完成所有编码(这是一门设计课程)。在我们的一个项目中,我想做一些事情,但很难找到如何去做。似乎大多数人所做的只是修改他们自己的 smalltalk 版本来做他们需要它做的事情。我不能这样做,因为如果我的教授没有与我相同的内置方法,这会导致他的计算机出现错误。

这是我想要做的:

随机数。我需要创建一个介于 1 到 1000 之间的随机数。现在我正在通过这样做来伪造它

rand := Random new.
rand := (rand nextValue) * 1000.
rand := rand asInteger.

这给了我一个介于 0 和 1000 之间的数字。有没有办法在一个命令中做到这一点?类似于

Random between: 0 and: 1000

和/或语句。这让我大吃一惊。我尝试了几种不同的配置

(statement) and: (statement) ifTrue...
(statement) and (statement) ifTrue...

所以我用嵌套的 ifTrue 语句来伪造它:

(statement) ifTrue:[
    (statement) ifTrue:[...

smalltalk 中的正确做法和/或 Random 是什么?

【问题讨论】:

  • 将两个不同的问题分成两个单独的页面会很有用。

标签: random smalltalk logical-operators


【解决方案1】:

问题是

 (expr) and: (expr) ifTrue: aBlock

被解析为方法and:ifTrue: 如果您查看布尔类(特别是 True 或 False),您会注意到 ifTrue: 只是一个常规方法,并且没有方法 and:ifTrue: 存在 - 但是, 平原和: 确实。所以为了明确这是两条消息,写

((expr) and: (expr)) ifTrue: aBlock

对于较长的布尔组合,请注意还有方法 and:and: and and:and:and: 已实现。

【讨论】:

  • 但这是不完整的,因为 and: 需要一个块,正如 rydier 所说。并且没有该列将被解析为一元消息并在之后导致解析错误,因为它只期望它之后的消息,而不是完整的表达式。
【解决方案2】:
(1 to: 1000) atRandom

【讨论】:

    【解决方案3】:

    如果您使用的是 VisualWorks,并且: 将块作为参数,那么您应该这样写:

    (aBoolean and: [anotherBoolean]) ifTrue: [doSomething].
    

    还有&,不以块为参数,

    aBoolean & anotherBoolean ifTrue:[doSomething].
    

    不同之处在于:仅当第一个布尔值为真时才评估块中的内容(类似于 java),而& 始终评估两者。

    因此and: 如果第二个条件计算量大,或者它包含仅在第一个条件为真时才应发生的状态更改,则可以派上用场。 (虽然这通常是一个糟糕的设计)。

    至于 Random,只要您提供自定义方法 Random >> between: and: 以及其余代码,它就可以在您的教授计算机上正常运行。具体如何做,取决于你应该以何种形式提交作业。

    【讨论】:

      【解决方案4】:

      至于随机问题:这取决于您使用的 ST 版本。在 Squeak 3.9 中,有 Random>>#nextInt:,它被记录为“Answer a random integer in the interval [1, anInteger].”。它的实现是

      (self next * anInteger) truncated + 1
      

      所以我这里有两个cmets:

      1. 你真的应该学会使用课堂浏览器。这可以回答(常见的)问题“我可以向 X 类的对象发送什么消息”
      2. 在 ST 中,向现有类添加新方法是很常见的。因此,如果您希望 Random 具有 between:and:,只需添加它,例如作为

        between: low and: high      
           ^(self next * (high-low+1)) truncated + low
        

      【讨论】:

      • 嗯,就是这样。我们根本没有使用 Squeak。我们使用的版本只有 next 和 nextValue。
      • 不过,您可以添加任何您认为有用的新方法。
      • Martin 所指的机制是命名类扩展。基本上,您可以在其他地方定义的类上定义一个方法,并且仍然将该方法与您的其余代码打包在一起,无论是在文件输出中还是在提交中。具体方法取决于方言,但您还没有告诉我们您使用的是哪一种……
      【解决方案5】:

      简单来说,不懂Smalltalk方言,只能给出一个笼统的答案。你提出随机问题的方式,是的,如果你的教授需要一个通用的答案,这是唯一的方法。

      关于和/或陈述问题,

      和/或语句。这让我大吃一惊。我尝试了几种不同的配置

      (statement) and: (statement) ifTrue...
      (statement) and (statement) ifTrue...
      

      你想尝试的是:

      (statement) and: [statement] ifTrue: [ ... ]
      

      注意括号,and: 方法将块作为参数。

      【讨论】:

        【解决方案6】:

        创建几个 1 到 1000 之间的随机整数
        首先创建一个随机数系列。只做一次。

        然后通过从系列中获取下一个数字来创建一个新的随机数。根据需要重复。

        aRandomSeries := Random new .
            "Seed a new series of random numbers"  
        
        aRandomInt := aRandomSeries newInt: 1000 . 
            "generate a random integer between 0 and 1000"
        
        anotherRandomInt := aRandomSeries newInt: 1000 .
            "generate another random integer between 0 and 1000"
        

        逻辑运算

        aBoolean 将回复and:or:。它们都采用块参数

        这是它们的工作原理。

        and: alternativeBlock
        如果接收者为真,则回答alternativeBlock的值;否则在不评估替代块的情况下回答 false。

        or: alternativeBlock
        如果接收者为假,则回答alternativeBlock的值;否则在不评估替代块的情况下回答 true。

        例如
        ( 3 > 2 ) or: [ 3 < 4 ] ifTrue: [ ]
        aBoolean and: [ anotherBoolean ] ifFalse: [ ]

        但是,Squeak 和 Pharo Smalltalks 都将接受括号中的参数 ( )
        Dolphin Smalltalk 不会,并且严格要求块参数的标准 Smalltalk 语法。

        其他相关方法:

        & 一个 AND,不需要方括号(即块)参数
        | 一个 OR 不需要方括号(即块)参数
        &| 在 Amber、Cuis、Gnu、Pharo、Squeak、VisualAge 和 VisualWorks Smalltalks 中工作。

        Squeak Smalltalk 还提供:
        and:and: }
        and:and:and: } 这些接受多个块参数
        and:and:and:and }

        or:or: }
        or:or:or: } 这些接受多个块参数
        or:or:or:or: }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-08
          • 2010-09-22
          • 2014-08-11
          相关资源
          最近更新 更多