chlh_jd 发表于 2010-9-1 23:47:00

公布“伪答案”的时间还没到啊,大家多SHOW点吧

chlh_jd 发表于 2010-9-1 23:55:00

题目9:编写一个递归函数,用新元素new替换表lst中第i项元素,这里i = 0 1 2 3 ...
我把QJ-CHEN老师的源码延伸了下,改为支持2重表,方便诸如矩阵列表使用

;;;by GSLS(SS)
;;;(ch-lst 4 '(2 2) '((1 2 3) (2 4 5) (3 5 6)))返回((1 2 3) (2 4 4) (3 5 6))
(defun ch-lst (new i lst / j)
(if (null lst)
    (*error* "No list")
    (if (numberp i)
      (cond ((zerop i)
      (cons new (cdr lst))
   )
   ((> i 1)
      (cons
      (car lst)
      (ch-lst   new(1- i)(cdr lst))
      )
   )
   (T lst)
      )
      (progn
(setq j (cadr i) ;_这里您可以不定义局部变量j,和重定义i,但效率将较低
       i (car i)
)
(if j
   (ch-lst (ch-lst new j (nth i lst)) i lst)
   (ch-lst new i lst)
)
      )
    )
)
)

chlh_jd 发表于 2010-9-10 20:44:00

素数判断,我是这样写的

(defun is-prime (n)
(defun is-prime-helper (n try)
    (if (= n try)
      T
      (if (zerop (rem n try))
nil
(is-prime-helper n (+ try 1))
      )
    )
)
(is-prime-helper n 2)
)

qjchen 发表于 2010-9-12 09:12:00

就是说,假如不定义一个其他函数,就is-prime 本身还是无法递归的:)

chlh_jd 发表于 2010-9-19 17:28:00

<p>同意qj-chen老师的观点,is-prime不定义局部函数,本身是无法递归的</p>

chlh_jd 发表于 2010-9-19 17:34:00

第7题powerset递归函数我是这样写的

;;;列出表中元素所有可能组合,包括空集,按先后顺序
;;;(powerset (list 1 2 3)) 返回 ((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) nil)
(defun powerset (lst)
(if (null lst)
    (list nil)
    (append ;_这里的append可以采用自定义myappend函数
      (mapcar '(lambda (x) ;_这里的mapcar可以采用qj-chen老师写的自定义mymapcar函数,lamda可以采用defun定义局部函数
   (cons (car lst) x)
      )
       (powerset (cdr lst))
      )
      (powerset (cdr lst))
    )
)
)

chlh_jd 发表于 2010-9-19 17:44:00

7a这道题目有点难,牵涉到时间测试,这里先提供一个简易时间测试函数(或许您有更好的,权当献丑吧^_^)

;;;小函数测试时间,ti为使用次数,funname为函数名,funarglist为函数funname的参数列表
;;;如(powerset (list 1 2 3))测试100000次运行时间使用代码为
;;;    (times 100000 'powerset (list (list 1 2 3)))
(defun times (ti funname funarglist / t1 t2)
(setq t1 (getvar "date"))
(repeat ti
    (vl-catch-all-apply
      funname
      funarglist
    )
)
(setq t2 (getvar "date"))
(princ "函数:")
(princ funname)
(princ (strcat "运行" (rtos ti 2 0) "次" ))
(princ "测试结果")
(princ (menucmd (strcat "M=$(edtime,"
   (rtos (- t2 t1) 2 16)
   ",HH:MM:SS:MSEC)"
    )
)
)
)

qjchen 发表于 2010-9-19 19:53:00

:) 谢谢chlh_jd的组合函数,写的很简洁

chlh_jd 发表于 2010-9-21 20:36:00

7a编写一个faster-powerset 递归函数,效率比正向排序高一倍;大家测试下列代码,看看有没有更好的写法

;;;by GSLS(SS)
;;;(faster-powerset (list 1 2 3))
(defun faster-powerset (lst)
(defun faster-powerset-helper (p lst)
    (if (null lst)
      p
      (faster-powerset-helper
(append
   (mapcar '(lambda (x)
       (cons (car lst) x)
   )
    p
   )
   p
)
(cdr lst)
      )
    )
)
(faster-powerset-helper (list nil) lst)
)

chlh_jd 发表于 2010-9-25 22:54:00

第10题,find-matching-pair里面用到了适应函数TEST,在递归里面引用函数名一般是不需要加上quote的,有2种写法分别如下:

方法一,使用nth函数

;;;
;;;
;|测试1
(find-matching-pair = (list 1 2 3 4 5 7 8 1 2))
|;
;|测试2
(find-matching-pair
(lambda (a b) (= a (* b 2)))
(list 1 2 3 4 5 7 8 1 2)
)|;
(defun find-matching-pair (test lst / find-matching-pair-helper)
(defun find-matching-pair-helper (test lst i j)
    (if (= i (length lst))
      (princ "no matching pair found")
      (if (= j (length lst))
(find-matching-pair-helper test lst (+ i 1) 0)
(if (and (/= i j)
   (test (nth i lst)
         (nth j lst)
   )
   )
   (cons (nth i lst) (nth j lst))
   (find-matching-pair-helper test lst i (+ j 1))
)
      )
    )
)
(find-matching-pair-helper test lst 0 0)
)

方法二、使用前面写过的remove-nth

(defun find-matching-pair (test lst)
(defun find-matching-pair-helper (test orig left others)
    (if (null left)
      (princ "no matching pair found")
      (if (null others)
(if (null (cdr left))
   (princ "no matching pair found")
   (find-matching-pair-helper
   test
   orig
   (cdr left)
   (remove-nth
       (- (length orig)
   (length (cdr left))
       )
       orig
   )
   )
)
(if (test (car left) (car others))
   (cons (car left) (car others))
   (find-matching-pair-helper test orig left (cdr others))
)
      )
    )
)
(find-matching-pair-helper test lst lst (cdr lst))
)
页: 1 [2] 3 4
查看完整版本: lisp应用递归算法10题