3 回答

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超6個(gè)贊
您的問題不是很具體,關(guān)于所計(jì)算的內(nèi)容。我假設(shè)您要?jiǎng)?chuàng)建某種形式的元素頻率表。有幾種方法可以解決此問題。(如果您使用的是Racket,請(qǐng)向下滾動(dòng)至底部以找到我的首選解決方案。)
便攜式,純功能,但冗長(zhǎng)且緩慢
此方法使用關(guān)聯(lián)列表(alist)來保存元素及其計(jì)數(shù)。對(duì)于傳入列表中的每個(gè)項(xiàng)目,它將在列表中查找該項(xiàng)目,并遞增其存在的值;如果不存在,則將其初始化為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))
遞增是有趣的部分。為了實(shí)現(xiàn)純功能,我們實(shí)際上不能更改alist的任何元素,而是必須排除要更改的關(guān)聯(lián),然后將該關(guān)聯(lián)(帶有新值)添加到結(jié)果中。例如,如果您具有以下列表:
((foo . 1) (bar . 2) (baz . 2))
并想在baz的值上加1 ,則創(chuàng)建一個(gè)新的列表,該列表不包括baz:
((foo . 1) (bar . 2))
然后添加baz的新值:
((baz . 3) (foo . 1) (bar . 2))
第二步是exclude函數(shù)的功能,并且可能是函數(shù)中最復(fù)雜的部分。
便攜式,簡(jiǎn)潔,快速但無功能
一種更直接的方法是使用哈希表(來自SRFI 69),然后針對(duì)列表中的每個(gè)元素逐一對(duì)其進(jìn)行更新。由于我們直接更新哈希表,因此它不是純粹的功能。
(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)))
純功能,簡(jiǎn)潔,快速但不可攜帶
此方法使用特定于球拍的哈希表(與SRFI 69的哈希表不同),該哈希表確實(shí)支持純功能的工作流程。另一個(gè)好處是,該版本也是三個(gè)版本中最簡(jiǎn)潔的版本。
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
您甚至可以for對(duì)此進(jìn)行理解:
(define (bagify lst)
(for/fold ((ht #hash()))
((key (in-list lst)))
(hash-update ht key add1 0)))
這比可移植SRFI 69哈希庫的缺點(diǎn)更能說明問題,而不是Scheme的任何特定失敗都無法完成純功能任務(wù)。使用正確的庫,可以輕松且功能上地實(shí)現(xiàn)此任務(wù)。

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超11個(gè)贊
在像Scheme這樣的函數(shù)式編程語言中,您必須有所不同,并利用構(gòu)造列表的方式。無需通過增加索引來遍歷列表,而是遞歸地遍歷列表。您可以使用car
(單個(gè)元素)刪除列表的頭部,可以使用cdr
(列表本身)獲取列表的尾部,并且可以將頭部和其尾部粘合在一起cons
。您的功能概述如下:
您必須“遞歸”要搜索的元素以及該函數(shù)每次調(diào)用的當(dāng)前計(jì)數(shù)
如果您擊中空白列表,則列表已完成,您可以輸出結(jié)果
如果列表中的汽車等于您要查找的元素,請(qǐng)使用列表的cdr和計(jì)數(shù)器+ 1遞歸調(diào)用該函數(shù)
如果不是,請(qǐng)使用列表的cdr和與以前相同的計(jì)數(shù)器值遞歸調(diào)用該函數(shù)
- 3 回答
- 0 關(guān)注
- 695 瀏覽
添加回答
舉報(bào)