在 SML 中是否可以找到串列中最小數字的出現次數?
我有代碼來查找一個數字的出現次數,但我對如何找到最小值并使用它來查找最小 num 的數量感到困惑。
fun occurrences(nil, n)=0
| occurrences(ls, n) =
if hd(ls)=n then occurrences(tl(ls),n) 1
else occurrences(tl(ls),n) 0;
謝謝!
uj5u.com熱心網友回復:
您可以撰寫一個函式,在您遍歷串列時跟蹤最小值及其計數。
我們可以通過實作一個尾遞回函式來做到這一點helper,該函式保持當前最小值的值和該專案出現的次數。
然后我們可以min_count通過 let-in-end 塊將其包裝在另一個函式中。
例如:
fun min_count [] = 0 (* the empty list has zero items in it *)
| min_count (x :: xs) =
let
(* when we reach the end of the list, return the accumulated count *)
fun helper (_, n) [] = n
| helper (m, n) (y :: ys) =
(* if we find a new minimum, reset the count *)
if y < m then helper (y, 1) ys
(* if the current list item is larger than the min, ignore it *)
else if y > m then helper (m, n) ys
(* if we've found another instance of the min, add one to the count *)
else helper (m, n 1) ys
in
(* first item appears once *)
helper (x, 1) xs (* first item appears once *)
end;
uj5u.com熱心網友回復:
我們也可以很容易地用折疊來定義它。
當我們折疊串列時,我們需要跟蹤哪些資訊?
- 當前最小值。
- 最小值的當前計數。
使用List.foldl這將是我們表示為元組的初始值。我們將選擇最大值int(至少在我的機器上)。隨意更改此值是明智的。我們將從零計數開始。
let
fun f(x, (min, count)) =
if x = min then (min, count 1)
else if x < min then (x, 1)
else (min, count)
in
List.foldl f (1073741823, 0) [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 3, 3, 5]
end;
我們每次應用的函式都很簡單。它模式匹配那個初始值元組給我們min和count。如果min等于串列(當前值x),然后x是最小值的另一個發生,我們增加count1。如果是小于min然后我們有一個新的最低值,所以我們傳遞沿,并開始了在1與count. 否則,什么都不會改變。
可選的,我們可以用這個清理了一下Int.compare,case和走樣(min, count)的init。
let
fun f(x, init as (min, count)) =
case Int.compare(x, min) of
EQUAL => (x, count 1)
| LESS => (x, 1)
| _ => init
val init = (1073741823, 0)
val lst = [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 3, 3, 5]
in
List.foldl f init lst
end;
補充兩點:
- 這個實作是尾遞回的。
- 如果它在一個空串列上運行,或者我們開始的最小值實際上小于串列中的最小值,我們就會知道,因為
count結果元組的組成部分將是0。我們可以輕松地對結果進行模式匹配并進行檢查。
uj5u.com熱心網友回復:
假設您應該occurrences在解決方案中使用您的函式,請撰寫一個查找最小值的函式,
fun minimum [x] = x
| minimum (x::xs) = let
val min = minimum xs
in
if x < min then x else min
end
然后使用它,
occurrences(the_list, minimum the_list)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360857.html
下一篇:有沒有辦法替換串列中的隨機單詞?
