亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

計算Scheme中列表中元素的出現?

計算Scheme中列表中元素的出現?

C++
人到中年有點甜 2019-11-04 13:12:22
例如,如果我可以使用命令式語言的數組或C ++中的map(樹結構),則這非常容易。在計劃中,我不知道如何開始這個想法?誰可以幫我這個事?
查看完整描述

3 回答

?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

您的問題不是很具體,關于所計算的內容。我假設您要創建某種形式的元素頻率表。有幾種方法可以解決此問題。(如果您使用的是Racket,請向下滾動至底部以找到我的首選解決方案。)


便攜式,純功能,但冗長且緩慢

此方法使用關聯列表(alist)來保存元素及其計數。對于傳入列表中的每個項目,它將在列表中查找該項目,并遞增其存在的值;如果不存在,則將其初始化為1。


(define (bagify lst)

  (define (exclude alist key)

    (fold (lambda (ass result)

            (if (equal? (car ass) key)

                result

                (cons ass result)))

          '() alist))

  (fold (lambda (key bag)

          (cond ((assoc key bag)

                 => (lambda (old)

                      (let ((new (cons key (+ (cdr old) 1))))

                        (cons new (exclude bag key)))))

                (else (let ((new (cons key 1)))

                        (cons new bag)))))

        '() lst))

遞增是有趣的部分。為了實現純功能,我們實際上不能更改alist的任何元素,而是必須排除要更改的關聯,然后將該關聯(帶有新值)添加到結果中。例如,如果您具有以下列表:


((foo . 1) (bar . 2) (baz . 2))

并想在baz的值上加1 ,則創建一個新的列表,該列表不包括baz:


((foo . 1) (bar . 2))

然后添加baz的新值:


((baz . 3) (foo . 1) (bar . 2))

第二步是exclude函數的功能,并且可能是函數中最復雜的部分。


便攜式,簡潔,快速但無功能

一種更直接的方法是使用哈希表(來自SRFI 69),然后針對列表中的每個元素逐一對其進行更新。由于我們直接更新哈希表,因此它不是純粹的功能。


(define (bagify lst)

  (let ((ht (make-hash-table)))

    (define (process key)

      (hash-table-update/default! ht key (lambda (x) (+ x 1)) 0))

    (for-each process lst)

    (hash-table->alist ht)))

純功能,簡潔,快速但不可攜帶

此方法使用特定于球拍的哈希表(與SRFI 69的哈希表不同),該哈希表確實支持純功能的工作流程。另一個好處是,該版本也是三個版本中最簡潔的版本。


(define (bagify lst)

  (foldl (lambda (key ht)

           (hash-update ht key add1 0))

         #hash() lst))

您甚至可以for對此進行理解:


(define (bagify lst)

  (for/fold ((ht #hash()))

            ((key (in-list lst)))

    (hash-update ht key add1 0)))

這比可移植SRFI 69哈希庫的缺點更能說明問題,而不是Scheme的任何特定失敗都無法完成純功能任務。使用正確的庫,可以輕松且功能上地實現此任務。


查看完整回答
反對 回復 2019-11-04
?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

在像Scheme這樣的函數式編程語言中,您必須有所不同,并利用構造列表的方式。無需通過增加索引來遍歷列表,而是遞歸地遍歷列表。您可以使用car(單個元素)刪除列表的頭部,可以使用cdr(列表本身)獲取列表的尾部,并且可以將頭部和其尾部粘合在一起cons。您的功能概述如下:

  • 您必須“遞歸”要搜索的元素以及該函數每次調用的當前計數

  • 如果您擊中空白列表,則列表已完成,您可以輸出結果

  • 如果列表中的汽車等于您要查找的元素,請使用列表的cdr和計數器+ 1遞歸調用該函數

  • 如果不是,請使用列表的cdr和與以前相同的計數器值遞歸調用該函數


查看完整回答
反對 回復 2019-11-04
  • 3 回答
  • 0 關注
  • 694 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號