Scheme 计划家庭作业帮助

Scheme 计划家庭作业帮助,scheme,Scheme,好的,我在课堂上开始了一门新的语言。我们正在学习这个计划,我不知道怎么做。当我说学习一门新语言时,我的意思是扔掉一份家庭作业,让他把它弄明白。他们中的一些人把我难住了 我的第一个问题是: 编写一个Scheme函数,如果参数是一个包含n个a后跟n个b的列表,则返回true(布尔常量#t)。否则就错了 以下是我现在拥有的: (define aequalb (lambda (list) (let ((head (car list)) (tail (cdr list))) (if

好的,我在课堂上开始了一门新的语言。我们正在学习这个计划,我不知道怎么做。当我说学习一门新语言时,我的意思是扔掉一份家庭作业,让他把它弄明白。他们中的一些人把我难住了

我的第一个问题是:

编写一个Scheme函数,如果参数是一个包含n个a后跟n个b的列表,则返回true(布尔常量#t)。否则就错了

以下是我现在拥有的:

(define aequalb
  (lambda (list)
    (let ((head (car list)) (tail (cdr list)))
      (if (= 'a head)
          ((let ((count (count + 1)))
             (let ((newTail (aequalb tail))))
             #f
             (if (= 'b head)
                 ((let ((count (count - 1)))
                    (let ((newTail (aequalb tail))))
                    #f
                    (if (null? tail)
                        (if (= count 0)
                            #t
                            #f)))))))))))

我知道这是完全错误的,但我一直在努力,所以请对我放轻松。任何帮助都将不胜感激。

列出的不是关键词吗?我总是用“alist”作为变量名来绕开它

您可以像现在这样使用计数器,但我可能选择具有以下条件的递归函数:

情人:情人

如果列表为nil,则返回true

如果第一个元素不是

如果最后一个元素不是b,则为false

(aequalb(倒车档)(cdr)(倒车档)(cdr列表()));;挑出前面和后面,然后递归

在这种情况下,您可能需要编写一个反向函数。。。不记得它是否已经在那里了


另外,从语法的角度来看,您不需要引入lambda表达式

(define (foo arg) (+ 1 arg))

是一个名为foo的函数,它接受一个数字并向其中添加一个。你可以称之为(foo 1)

列表不是关键字吗?我总是用“alist”作为变量名来绕开它

您可以像现在这样使用计数器,但我可能选择具有以下条件的递归函数:

情人:情人

如果列表为nil,则返回true

如果第一个元素不是

如果最后一个元素不是b,则为false

(aequalb(倒车档)(cdr)(倒车档)(cdr列表()));;挑出前面和后面,然后递归

在这种情况下,您可能需要编写一个反向函数。。。不记得它是否已经在那里了


另外,从语法的角度来看,您不需要引入lambda表达式

(define (foo arg) (+ 1 arg))

是一个名为foo的函数,它接受一个数字并向其中添加一个。你可以称之为(foo 1)

我会看一下
和map
,它们之间的关系使这个问题变得非常简单。哦,至少现在,我可能会试图忘记,
let
甚至是存在的。这并不是说它有什么特别的问题,但我想你将遇到的大多数问题(至少在一段时间内)都不需要它。

我会看看
和map
take
drop
,这些问题(在它们之间)使这个问题变得非常简单。哦,至少现在,我可能会试图忘记,
let
甚至是存在的。这并不是说它有什么特别的问题,但我想你将遇到的大多数问题(至少在一段时间内)都不需要它。

我从编程语言的精髓中学到的一个技巧是始终通过处理两个重要的情况来编写递归列表函数:首先是null(列表末尾)和notnull

因此,列表函数的基本结构如下所示:

(define some-list-function 
  (lambda (list)
    (if (null? list)
        #f
        (do-some-work-here (head list)
                           (some-list-function (tail list))))))
通常你(1)检查空值(2)在头部做一些工作,(3)在尾部重复

您需要做的第一件事是确定空列表的答案是什么。不是t就是f,但哪个呢?空列表中的
a
数是否与
b
数相同

接下来,您需要对递归案例做一些处理。你的基本方法很好(尽管你的示例代码是错误的):当你看到
a
时,保持计数上升,当你看到
b
时,保持计数下降。问题是如何跟踪计数。Scheme没有循环,所以你必须用递归做所有的事情。这意味着您需要传递一个额外的计数器变量

(define some-list-function 
  (lambda (list counter)
    (if (null? list)
        ; skip null's code for a second
现在,您必须确定头部是否为
'a
,如果是,则增加
计数(否则减少)。但是没有count变量,只是在函数之间传递。那么怎么做呢

嗯,你必须在线更新它,就像这样:

(some-list-function (tail list) (+ 1 count))
顺便说一句,除了数字以外,不要使用
=
。新的、更酷的Lisp允许这样做,但Scheme要求您对符号使用
eq?
,对数字使用
=
。因此,对于您的
'a
'b
测试,您需要

(if (eq? 'a (head tail)) ...)
; not
(if (= 'a (head tail)) ...)
我希望这有帮助。我想我把所有的作品都给了你,虽然有些东西我略过了。您现在需要更改null大小写以检查计数。如果结尾不是
=0
,则答案为false

您还应该维护一个单独的标志变量,以确保一旦切换到
'b
,如果看到另一个
'a
,则返回
#f
。这样,像
”(a a b b)
这样的列表就不会错误地通过。通过添加另一个函数参数并在每次递归调用时传递值,以与我在上面添加的
计数器
相同的方式添加标志

最后,若你们的老师真的并没有给你们任何帮助,也不会给你们任何帮助,那个么你们可能想读一本关于Scheme的基础书。我自己也没用过这些书,但我听说它们很好:,或者呃,嗯,我以为网上有第三本书是免费的,但我现在找不到。我想如果你有很多额外的时间,想让你的头脑清醒,你可以阅读。它教授了一些编程语言的方案和很多内容


*它确实有一些这样的功能,但最好暂时忽略它们。

我从编程语言的精髓中学到的一个技巧是始终通过处理两种重要情况来编写递归列表函数:第一种是null(列表末尾)和notnull

因此,列表函数的基本结构如下所示:

(define some-list-function 
  (lambda (list)
    (if (null? list)
        #f
        (do-some-work-here (head list)
                           (some-list-function (tail list))))))
通常你(1)检查空值(2)在头部做一些工作,(3)在尾部重复

您需要做的第一件事是确定空列表的答案是什么。不是t就是f,但哪个呢?是否为空