-1

我正在编写一个函数,该函数需要一个战斗的骑士列表。运行他们的战斗的代码正在运行(jousting-game),现在我正在编写一个锦标赛系统,但我无法让我的锦标赛轮工作。正如我所说,它需要一个骑士列表,让他们递归地战斗,直到每个人都战斗,然后返回两个列表,一个是胜利者,一个是失败者。我已经尝试了我所知道的一切,无论我做什么,我都会收到错误并且代码拒绝工作,我不明白为什么。这是我到目前为止所写的:

(define (playTourneyRound knightList)
    (
        (cond 
            ((> (length knightList) 1)
                (let (
                    (winner (jousting-game (car knightList) (cadr knightList)))
                    (winners (list))
                    (losers (list))
                    (results (playTourneyRound (cddr knightList)))
                )
                (if (= winner 1) (winners (append winners (list (car knightList)))) (winners (append winners (list (cadr knightList)))))
                (winners (append (car results)))
                (losers (list (cadr knightList) (cadr results)))
                (list winners losers)
                )
            )
            ((= (length knightList) 1)
                (list knightList)
            )
        )
        (list '() '())
    )
)

有人可以向我解释为什么我收到错误“非程序调用:#”,我以后如何避免这个错误?我确定我只是不了解重要的方案/lisp,我真的可以使用一个解释。

感谢大家的帮助,问题已经解决

4

2 回答 2

1

首先认为您应该知道方案是词法范围的。变量声明仅在它们声明的代码框架或子框架中才有意义。

你也用双括号打开,这通常不是你想要做的,除非内部集合返回一个函数并且你想要应用它。

你漂亮的印刷品已经过时了。Cond语句应该在单行上,或者排列在子句的第二个括号中。If只有三个子句,并且应该再次都在同一行上,或者在与第一个参数对齐的后续行上。语句的函数体let应与 let 的“e”或“t”对齐。在他们自己的行上的尾随括号通常是不受欢迎的。

以递归方式重复调用长度是不好的形式,length对列表长度的 O(n) 操作也是如此,只需检查列表是否为空或 cdr 是否为空

你真的需要内在的功能来做你想做的事情。(内部定义、letrec 或命名的 let 都可以)

如果你正在追加,就像(append <some-list> (list <some list element>))你做得不好。首先append是 O(n) 到第一个参数的长度。只需继续以相反的顺序累积结果,并在最后将其反转。

  (define (playTourneyRound knightList)
     (let loop ((knights-L knightList) ;;named let
                (winners (list))
                (losers (list)))
       (cond ((null? knight-L) (map reverse (list winners losers))) ;;length = 0
             ((null? (cdr knight-L)  ;;lenght = 1
              (loop (cdr knight-L)                                                
                    (cons (car knight-L) winners)
                    losers))
             (else       ;; length > 1
              (let* ((winner (jousting-game (car knight-L) (cadr knight-L)))
                        ;;assuming that jousting-game return the winning knight
                     (loser (if (equal? winner (car knight-L))
                                (cadr knight-L)
                                (car knight-L))))
                 (loop (cddr knight-L)
                       (cons winner winners)
                       (cons loser losers)))))))    
于 2014-03-06T18:07:22.880 回答
0

正如我在这里看到的,你有很多问题......

(define (playTourneyRound knightList)
  (
   ...
  )
)

您在这里有无用的括号,这意味着您将执行由(...). 由于您使用condthen跟随它(list '() '())。没有多大意义...

你可以写出这样的想法:

(define (playTourneyRound knightList)
  (begin
   ...
  )
)

但这在没有任何东西的情况下已经绰绰有余:

(define (playTourneyRound knightList)
  ...)

另外,我现在可以说的是,由于您所做的一切都没有副作用,因此它永远不会附加任何内容或更改任何对象您可能想要写的是:

(set! winners (append ...))
(set! loosers (...))

但是由于您没有调用其他任何内容,并且函数中的最后一条语句返回一个空列表列表......该函数不做任何事情并且不迭代元素列表。

你应该尝试一些更简单的东西。

于 2014-03-06T13:08:03.830 回答