根據這本書,這就是函式定義,
函式 scramble 接受一個非空元組,其中沒有引數大于它自己的索引,并回傳一個相同長度的元組。引數中的每個數字都被視為從它自己的位置到元組中更早一點的向后索引。每個位置的結果都是根據這個索引從當前位置倒數得到的。
這些是一些例子,
; Examples of scramble
(scramble '(1 1 1 3 4 2 1 1 9 2)) ; '(1 1 1 1 1 4 1 1 1 9)
(scramble '(1 2 3 4 5 6 7 8 9)) ; '(1 1 1 1 1 1 1 1 1)
(scramble '(1 2 3 1 2 3 4 1 8 2 10)) ; '(1 1 1 1 1 1 1 1 2 8 2)
這是實作,
(define pick
(λ (i lat)
(cond
((eq? i 1) (car lat))
(else (pick (sub1 i)
(cdr lat))))))
(define scramble-b
(lambda (tup rev-pre)
(cond
((null? tup) '())
(else
(cons (pick (car tup) (cons (car tup) rev-pre))
(scramble-b (cdr tup)
(cons (car tup) rev-pre)))))))
(define scramble
(lambda (tup)
(scramble-b tup '())))
uj5u.com熱心網友回復:
在這種情況下,使用非常小的語言版本意味著代碼足夠冗長,以至于理解演算法可能并不容易。
解決這個問題的一種方法是用更豐富的語言撰寫程式,然后計算出現在很明顯的演算法是如何在最小版本中實作的。讓我們選擇Racket作為豐富的語言。
Racket 有一個名為 的函式(和 Scheme 一樣)list-ref
:(list-ref l i)
回傳 的i
第一個元素l
,從零開始。
它還有一個很好的“序列”概念,幾乎是“可以迭代的東西”和一堆名稱以for
迭代序列開頭的結構。有兩個函式可以生成我們關心的序列:
in-naturals
生成自然數的無限序列,默認情況下從 開始0
,但從(in-naturals n)
開始n
。in-list
從串列中創建一個序列(串列實際上已經是一個序列,但in-list
使事情更清晰,謠言也更快)。
我們關心的迭代結構是for/list
迭代一些序列并將結果從其主體收集到一個串列中。
鑒于這些,演算法幾乎是微不足道的:我們想要沿著串列進行迭代,跟蹤當前索引,然后進行適當的減法以沿著串列往后選擇一個值。唯一重要的一點是處理基于零和一的索引。
(define (scramble l)
(for/list ([index (in-naturals)]
[element (in-list l)])
(list-ref l ( (- index element) 1))))
事實上,如果我們in-naturals
計算 from1
我們可以避免尷尬的加 1:
(define (scramble l)
(for/list ([index (in-naturals 1)]
(element (in-list l)))
(list-ref l (- index element))))
現在看這段代碼,即使不了解Racket,演算法也很清楚,可以查一下書中給出的答案:
> (scramble '(1 1 1 3 4 2 1 1 9 2))
'(1 1 1 1 1 4 1 1 1 9)
現在還有待弄清楚書中的代碼如何實作相同的演算法。這很繁瑣,但是一旦你知道演算法是什么,它應該很簡單。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/493576.html
上一篇:C中的堆疊和遞回
下一篇:python函式中的遞回呼叫