如何解决方案中列表的运行长度编码R5RS
(Question Details image -- describes RLE encoding)
我的(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))))))
解决方法
我不会回答如何解决游程编码问题,而是基本的语法问题。
其摘要是:在许多编程语言中,通常以数学符号表示,括号用来控制操作的顺序,并且通常是或多或少是可选的。因此,例如1 + 2 * 3
可能意味着“将2乘以3,然后将1加到结果中”,而(1 + 2) * 3
则意味着“将1和2加,然后将结果乘以3”。但是1 + (2 * 3)
与1 + 2 * 3
的含义相同,也与(((1 + (2 * 3))))
的含义相同。
在Scheme或Lisp系列语言中从来没有这种情况。在这些语言中,括号是该语言语法的一部分,并且它们永远不是可选的:它们必须存在或不存在。
因此,尤其是Scheme中表达式的语法的简化版本可能是:表达式要么是
- 一些原子性的东西,例如变量引用;
-
(
op ...)
之类的格式,其中 op 是某种运算符。
在第二种情况下,括号不是可选的:它们是该语言语法的一部分。特别是如果您考虑这样的表达式
((foo ...))
然后与第二种情况匹配,其中 op 现在整体为(foo ...)
(并且没有参数),而那个又与之匹配第二种情况是 op 为foo
。所以这是一个表达式,其运算符是另一个表达式,而那个表达式的运算符是foo
:它不是不是用一些可选括号括起来的表达式,并且特别是((foo ...))
与(foo ...)
相同的情况不是 。
因此if
的语法为:(if
表达式 必然的 替代 )
。好吧,让我们看看您的if
:
(if ((equal? (car coins) (cadr coins)))
...
...)
所以这里的表达式是((equal? (car coins) (cadr coins)))
。好吧,这符合(
op ... )
的情况,其中 op 为(equal? (car coins) (cadr coins))
,这又匹配了这种情况,因此它将评估此结果以返回#t
或#f
。因此,表达式与(#t)
或(#f)
是同一件事。 #t
或#f
是布尔值:它们不是您可以调用为函数的东西。
那至少是代码中的错误之一。还有其他一些,但这似乎是最重要的,因为这也是您在评论另一个答案时犯的错误。
总结:括号在Scheme中绝不是可选的:语言的语法要求使用或禁止使用括号。
另一种表达方式是,在“传统的Algol风格”语言中,括号通常有两个作用:
- 它们是语法的关键部分和强制部分,通常用于函数自变量,例如
f(x,...)
,但有时也用于其他语法目的,例如C say中的if (...) ...
; - 它们用于将表达式分组以控制有时需要但通常是可选的评估顺序。
在Lisp家族语言中,只有前一个目的存在。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。