用Scheme中的if查找所有可能的值

问题描述

| 我尝试做家庭作业,但是我很麻烦..关于公共汽车和航海者,有一些事实: 我尝试编写代码,以提供替代方法(可以是直接方法或最多一次转移)到旅行者的目的地。例如:
>(findways \'john)
(list (list \'b002))
>(findways \'merry)
(list (list \'b005) (list \'b001 \'b002))
>(findways \'lerry)
(list (list \'b006) (list \'b004 \'b003) (list \'b007 \'b008))
所以..首先找到不需要转移的方法,之后找到只需要转移的一种或多种方法... 在这些之后,我需要找到另一个函数的最短方法
>(findshort \'jhon)
(list \'b002)  ; this is because the only way is
>(findshort \'merry) 
(list \'b005)  ; this because b005 travel time is 8,b001+b002 is 15
>(findshort \'lerry)
(list \'b004 \'b003) ; this is because b006 is 18,b007+b008 is 16 but b004+b003 is 13
非常感谢 附注:我不允许使用!然后让     

解决方法

这不是一个完整的解决方案,但可以帮助您入门。 尝试将问题分解为更小的,更简单的函数,如下所示:
;; (define buses ...)
;; (define voyagers ....)

(define findways
   (lambda (voyager)
     (find_bus_routes (lookup_voyager_route voyager voyagers) buses)))

(define lookup_voyager_route
  (lambda (voyager voyager_lst)
    (if (null? voyager_lst)
        \'()
        (if (equal? voyager (caar voyager_lst))
            (cdar voyager_lst)
            (lookup_voyager_route voyager (cdr voyager_lst))))))

(define find_bus_routes
  (lambda (sd_lst bus_routes)
    (if (or (null? sd_lst) (null? bus_routes))
        \'()
        (if (equal? (car sd_lst) (cadar bus_routes))
            ;; perfect match
            (if (equal? (cadr sd_lst) (caddar bus_routes)) 
                (cons (caar bus_routes) ;; keep bus number
                      (find_bus_routes sd_lst (cdr bus_routes)))
                ;; partial match could be improved
                (cons (list (caar bus_routes) 
                            (match_route (caddar bus_routes)
                                         (cadr sd_lst) buses))
                      (find_bus_routes sd_lst (cdr bus_routes))))
            (find_bus_routes sd_lst (cdr bus_routes))))))

(define match_route
   (lambda (start dest routes)
     (if (null? routes)
         routes
         (if (and (equal? start (cadar routes))
                  (equal? dest (caddar routes)))
             (caar routes)
             (match_route start dest (cdr routes))))))
列出可能的路线后,很容易找出最短的距离。