2013-10-12 45 views
0
(define-struct position (name numshares share-price)) 

(define p1 
(cons (make-position "INT" 10 192) (cons (make-position "SSS" 4 42) 
empty))) 

mult是我的助手功能方案的結構和列表

(define (mult n) 
    (* (position-numshares n) 
    (position-share-price n))) 

常量採取的立場,numshares和位置,股價在列表中,並在一起相乘。

(define (const n) 
    (cond 
    [(empty? n) empty] 

    [(cons? n) 
     (+ (mult (first n)) 
       )])) 

我想要做的是將列表中的第一個添加到列表的其餘部分。相反,我只得到名單的第一名。所以如果我這樣做(const p1),我只能得到1920,但我想得到2088(10 * 192 + 4 * 42)。我已經嘗試了其餘的循環,但得到一個錯誤。我可能錯過了一些簡單的東西。幫助將不勝感激。

回答

2

首先,請注意,在一般情況下,你可以做的

(list a b) 

代替

(cons a (cons b empty)) 

所以你定義p1

(define p1 
    (list (make-position "INT" 10 192) 
     (make-position "SSS" 4 42))) 

這是更容易閱讀,並使得你的意圖更清楚。現在,要從(make-position "INT" 10 192)創建的結構中獲得1920,您已經定義了幫助程序mult。您可以在列表mapmult上列出您的清單p1,以獲得產品的新清單,即(1920 168)。然後,您可以在該列表上使用foldl+0來計算其總和。

(define (const lst) 
    (foldl + 0 (map mult lst))) 

(const p1) 
;=> 2088 

如果你不想使用foldmap(這可能是合理的,因爲map意味着一個新的列表中得到分配的),您可以手動編寫了這一點:

(define (const lst) 
    (let const ((sum 0) (lst lst)) ; pretty much an implementation of fold, but 
    (if (null? lst)    ; with the function + built in, and mult applied 
     sum      ; to each element before passing to + 
     (const (+ sum (mult (car lst))) 
       (cdr lst))))) 

(const p1) 
;=> 2088 

另一種替代方法是使用foldl,但不是通過+,而是傳入一個函數,該函數結合了+mult

(define (const3 lst) 
    (foldl (lambda (struct sum) 
      (+ (mult struct) sum)) 
     0 
     lst)) 

(const3 p1) 

作爲一個Common Lisper,對於我來說,Scheme的foldl過程沒有在函數應用到列表中的每個元素之前,沒有采用一個關鍵參數,這對我來說有點令人失望。在Common Lisp中,我們會寫(foldl/foldrreduce Common Lisp中):

(reduce '+ p1 :key 'mult) 
+0

@Josh有關褶皺的更多信息,你可以看看[這個回答關於壓扁列表(HTTP: //stackoverflow.com/a/19229532/1281433)和[這個關於比較值的答案](http://stackoverflow.com/a/19006055/1281433)。 (免責聲明:這些都是我的答案。) –