0

问题详细信息图片 - 描述 RLE 编码

我的函数中的(if ((equal? (car coins) (cadr coins)))那段代码rle不起作用,并且该函数停止工作。

 (define (element-index  lst element)
  (let loop ((counter 1) (temp lst))
    (if (= element (car temp))
        counter
        (loop (+ counter 1) (cdr temp)))))

 (define (rle coins)
   (cond ((null? coins) '()))
      (if ((equal? (car coins) (cadr coins)))
          (rle (cdr coins))
           (append '( cons (element-index (coins) (car coins)) (car coins))
                   '( cons (rle (cdr coins))))))
4

1 回答 1

2

我不会回答如何解决运行长度编码的问题,而是基本的语法问题。

总结是:在许多编程语言中,通常在数学符号中,括号用于控制操作的顺序,并且通常或多或少是可选的。因此,例如1 + 2 * 3可能意味着“将 2 乘以 3,然后将结果加 1”,而(1 + 2) * 3意味着“将 1 和 2 相加,然后将结果乘以 3”。but1 + (2 * 3)意思一样1 + 2 * 3which 意思和 一样(((1 + (2 * 3))))

在 Scheme 或 Lisp 系列语言中,情况并非如此。在这些语言中,括号是语言语法的一部分,它们从来都不是可选的:它们必须要么存在,要么不存在。

因此,特别是,Scheme 中表达式语法的简化版本可能是:表达式是

  • 一些原子的东西,比如变量引用;
  • (op ...这样的形式),其中op是某个运算符。

在第二种情况下,括号不是可选的:它们是语言语法的一部分。特别是如果您考虑像这样的表达式

((foo ...))

那么这与第二种情况相匹配,其中op现在(foo ...)是一个整体(并且没有参数),而又与第二种情况相匹配,其中opfoo. 所以这是一个表达式,它的操作符是另一个表达式,而那个表达式的操作符是foo: 它不是一个包裹在一些可选括号中的表达式,特别是它与.不同的情况。((foo ...))(foo ...)

那么,语法if是:(if 表达式 结果 交替)。好吧,让我们看看你的if

(if ((equal? (car coins) (cadr coins)))
    ...
    ...)

所以这里的表达式((equal? (car coins) (cadr coins)))。好吧,这匹配(op ...的)情况,其中op(equal? (car coins) (cadr coins)),而 this 又匹配该情况,因此它将评估 this 以返回#tor #f(#t)所以表达式与or是一样的(#f)。And #tor#f是布尔值:它们不是你可以调用为函数的东西。

这至少是您的代码中的错误之一。还有其他的,但这似乎是最重要的,因为这也是您在对另一个答案的评论中犯的错误。

总而言之:括号在 Scheme 中永远不是可选的:它们要么是必需的,要么是语言语法禁止的。


另一种说法是,在“传统的 Algol 风格”语言中,括号通常有两个目的:

  • 它们充当语法的关键和强制性部分,通常用于函数参数 as f(x, ...),但有时也用于其他语法目的,如if (...) ...C 说;
  • 它们用于对表达式进行分组以控制有时需要但通常是可选的评估顺序。

在 Lisp 系列语言中,只有前一个目的存在。

于 2020-10-31T09:47:45.240 回答