2014-10-02 38 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)))) 
相关问题