[英]Binary Search in smalltalk
Array extend [
Array class >> bin: val left: l right: r [
^ super binSearch: val left: l right: r
]
binSearch: val left: l right: r [
|arr iter|
arr := self.
[l == r]
ifTrue: [^ (-1)].
iter := (r + l)/2.
[arr at: iter == val]
ifTrue: [^iter].
[arr at: iter < val]
ifTrue:[^ super binSearch val left: l right: iter]
ifFalse: [^ super binSearch val left: iter right: r]
]
]
arr := #(3 6 9 10).
arr bin: 6 left: 1 right: 4.
這是我當前的代碼,但我收到編譯錯誤:“對象:新數組:4“<0x7fe20936e940>”錯誤:不理解 #bin:left:right:”。 我想知道我做錯了什么。
謝謝
第一部分對我來說毫無意義。 你的算法是遞歸的,所以它應該調用自己而不是委托給 class,這是一個不同的 object。
為此,請將super
替換為self
,然后將使用新參數再次調用相同的方法。
Array extend [
binSearch: val left: l right: r [
|arr iter|
arr := self.
l = r
ifTrue: [^ -1].
iter := (r + l) // 2.
(arr at: iter) = val
ifTrue: [^iter].
(arr at: iter) < val
ifTrue:[^ self binSearch: val left: l right: iter]
ifFalse: [^ self binSearch: val left: iter right: r]
]
]
補充說明
[布爾] ifTrue:
&friends 的接收者必須是Boolean
(即true
或false
)。 通過將條件括在方括號之間,您正在創建一個BlockClosure
。 我已經在適當的情況下將[...]
替換為(...)
,然后在不需要時將其刪除(請參閱下面的 [Precedence])。
[比較] 這是有爭議的,但是雖然條件l==r
並不完全錯誤,但是l=r
通常更好。 原因: ==
的語義對應於完全相同的 object(低級), =
的語義等於(或等價)。 您的算法不關心l
和r
是否由完全相同的 object 表示,它只需要知道兩個變量是否具有相同的 integer。 盡管這種區別在這種情況下無關緊要,但您可能會養成使用==
的習慣,這將在您處理其他類型的對象(vg LargeIntegers
等)的那一天失敗
[括號] ^ -1
不需要加括號。
[除法] 因為+
和/
是消息,所以在r + 1 / 2
中也不需要加括號。 但是,除法可能會產生一個Fraction
,您的代碼需要Integer
。 改為使用//
來獲取商。
[冒號] 您忘記了binSearch
之后的冒號。 這會產生 DNU 錯誤。
[優先級] arr at: iter
周圍需要括號,以便將此消息的結果與val
進行比較(請記住,優先級順序是:一元、二元、關鍵字)。
[ DNU ] 關於您收到的錯誤:您創建的選擇器是binSearch:left:right:
,但是您發送的消息bin:left:right:
未定義。
[ self ] 不需要將self
分配給其他東西:接收者不會隨着遞歸而改變。
[返回] 許多 Smalltalker 應該將返回符號^
移到最后一個表達式的開頭。
在 Smalltalk 中, arrays 是基於 1 的,廣泛接受的約定是在沒有找到索引時返回0
(而不是-1
)。
Array extend [
binSearch: val left: l right: r [
| iter |
l = r ifTrue: [^ 0].
iter := (r + l) // 2.
(self at: iter) = val ifTrue: [^iter].
^ (self at: iter) < val
ifTrue:[self binSearch: val left: l right: iter]
ifFalse: [self binSearch: val left: iter right: r]
]
]
建議
通過添加足夠的單元測試來練習和改進您的方法來完成您的工作。 我將我的答案限制在編碼風格上,而不是它的正確性。
添加以下方法,以便您的服務的客戶端在使用它時不需要冗長。
binSearch: value
^self binSearch: value left: 1 right: self size
binarySearch: value from: left to: right
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.