2014-10-02 77 views
2

我必須做一個函數,我必須計算列表中不是原始程序的數量。 下面是一些例子:SCHEME - 不是原始的程序數

(nprocs '(+ (cuadrado 1) (* 2 (inc1 3))))      => 0 
(nprocs (+ (cuadrado 1) (* 2 (inc1 3))))      => ERROR 
(nprocs (list + (list cuadrado 1) (list * 2 (list inc1 3)))) => 2 

我嘗試這樣做:

(define (cuadrado x) (* x x)) 
(define inc1 (lambda (x) (+ x 1))) 

(define nprocs 
    (lambda (fun) 
    (if (list? fun) 
     (if(procedure? (car fun)) 
      (+ 1 (nprocs (cdr fun))) 
      (nprocs (cdr fun))) 
     0) 
    ) 
) 

此代碼不能正常工作,希望有人可以提供幫助。 在此先感謝!

+3

首先是帶引號的列表,以便'+'和'*'的符號和不是程序。第二種方法是嘗試評估表達式,並將結果傳遞給'nprocs',而最後一個例子使用'list',以便可以對過程評估'+'和其他符號。只有最後一個是正確的。或者你可以使用'\'(,+(,curado 1)(,* 2(,inc1 3)))'' – Sylwester 2014-10-02 09:48:59

回答

2

列表由cons單元和原子組成。下面是處理名單,對你的方式計算非原始程序的規範方式:

(define (nprocs sxp) 
    (cond 
    ; cons cell -> process car and cdr 
    ((pair? sxp) (+ (nprocs (car sxp)) (nprocs (cdr sxp)))) 
    ; atom -> is it a procedure that is not a primitive? 
    ((and (procedure? sxp) (not (primitive? sxp))) 1) 
    ; atom, not or procedure or a primitive 
    (else 0))) 

測試:

> (nprocs '(+ (cuadrado 1) (* 2 (inc1 3)))) 
0 
> (nprocs (list + (list cuadrado 1) (list * 2 (list inc1 3)))) 
2 
1

nprocs程序必須遍歷列表列表,測試每個原子是否爲而不是原語的過程,並添加所有子列表的結果。這是簡單的,如果我們使用一個cond的條件,並使用標準模板用於遍歷一個列表的列表:

(define (nprocs fun) 
    (cond ((null? fun) 0) 
     ((not (pair? fun)) 
     (if (and (procedure? fun) (not (primitive? fun))) 1 0)) 
     (else (+ (nprocs (car fun)) 
       (nprocs (cdr fun)))))) 

它的工作原理,只要我們通過在列表中(而不僅僅是符號)實際步驟:

(nprocs (list + (list cuadrado 1) (list * 2 (list inc1 3)))) 
=> 2 

如果同一個非原始程序多出現一次,它將被計數幾次。如果這是一個問題,如果我們使用一個更加慣用的解決方案來利用內置的高階過程,則刪除重複項會更容易。例如,在球拍中:

(define (nprocs fun) 
    (count (lambda (e) (and (procedure? e) (not (primitive? e)))) 
     (remove-duplicates (flatten fun)))) 
相關問題