簡體   English   中英

我一直在嘗試在 Racket 和 ML 中實現這個 function

[英]I'm stuck trying to implement this function in Racket and ML

我有這個任務:

考慮一個列表,其中每個元素都是長度為 2 的嵌套列表。每個嵌套列表的第一個元素是 0 或 1。每個嵌套列表的第二個元素是一些 integer。下面是 Scheme 中的示例輸入。

 '((0 1) (1 2) (1 3) (0 4) (0 3))

出於這個問題的目的,我們將每個嵌套列表的第一個元素稱為鍵,將嵌套列表的第二個元素稱為值 現在考慮一個 function, count_by_cat ,它將這樣的列表作為輸入並產生一個二元素列表,其中

  • 第一個元素是所有以 0 為鍵的嵌套列表的值之和,並且
  • 第二個元素是所有以 1 為鍵的嵌套列表的值之和

在中實現count_by_cat

  • (a) 球拍,以及
  • (b) 毫升。

創建輔助函數可能會有所幫助。 也不要忘記mapfilterfilter不是 ML 的內置功能)。

我是 Racket 和 ML 的新手。 我堅持使用 Racket 中的訪問列表和內容。 ML 的一些幫助也很好。

那么建議您使用高階函數,例如mapfilter

事實上,將我們的數據作為一個整體來操作是很容易的,而不是在精神上一次只關注一個元素。 有些人可能會爭論哪種方法(即前一種方法)函數式編程范例的本質。

在球拍中,

(define (count_by_cat ls)

“返回一個二元列表”

    (list
      ;; .....
      ;; ..... ))

其中第一個元素是

      (sum-of

所有嵌套列表的值

        (map value

以 0 為鍵

           (filter (lambda (x) (= 0 (key x))) ls)))

第二個元素是所有嵌套列表的值之和

      (sum-of
        (map value

以 1 為鍵

           (filter (lambda (x) (= 1 (key x))) ls))) ))

所以我們需要定義訪問嵌套列表的輔助函數,

(define (key n) (car n))

(define (value n) (cadr n))

以及 function 的sum-of ,用於匯總列表中的數值:

(require math/base)

(define (sum-of ls)
    (sum ls))

這很容易編寫,也很容易維護。

性能更高的代碼將通過輸入一次完成所有操作,如另一個答案所示。 它將所有邏輯融合到一個循環體中。 編寫和維護起來可能更脆弱。

關於mapfilter的提示有點轉移注意力(而且關於它們不是 ML 語言的錯誤也是錯誤的); 幫助程序 function 非常有用,但它是您想要的折疊,它基本上使用列表的當前元素和累加器值調用 function,並使用它返回的值作為下一個元素的累加器,最終返回值整個折疊。

例如,在 ocaml 中,使用折疊對整數列表求和:

let sum = List.fold_left (+) 0 [ 1; 2; 3; 4; 5 ];;

(+)是中綴運算符+的 function 版本)。

或者您在 Racket 中的問題,使用for/fold comprehension ,並返回兩個值而不是雙元素列表,這在 Racket 和 Scheme 中更為慣用(在 ocaml 和大概標准 ML 中,您將返回一個雙元素元組而不是列表,並獲取元組列表)。

(define (count-by-cat lol)
  (for/fold ([zero-sum 0]
             [one-sum 0])
            ([elem (in-list lol)])
    (case (first elem)
      [(0) (values (+ zero-sum (second elem)) one-sum)]
      [(1) (values zero-sum (+ one-sum (second elem)))])))

您也可以使用foldl ,但for/fold通常更易於使用,尤其是在處理多個值或其他重要情況時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM