尝试学习Scheme的递归问题

时间:2016-09-23 00:00:00

标签: list dictionary recursion scheme traversal

我创建了一个将列表插入已定义的emtpy列表的函数。我插入的列表将有一些类型的关键字用于查找它(例如可能是名称或位置),后面跟一个嵌套列表,其中包含某种信息,例如通话记录的年龄或某事(同样这个只是我试图学习递归语法)。我的问题在于如何

  • 遍历更大的列表和

  • 让程序知道较大列表中有多个列表以及如何区分它们。

例如,如果我使用我的函数将列表'(John (AL 25 40 67) (CA 40 67 24))添加到空列表中,然后然后,则使用不同的名称添加另一个类似的列表,例如{{1 ,我怎么告诉它这些本质上是存储在名称下的两个不同的记录。

我的第一个思考过程是遍历列表,直到找到名称,然后从那里找到'(Sue (AZ 45 6 78))cdr以获取我需要提取的任何信息; 如果我开始carcdr最终不会超过该名称的记录?

car

这是我插入列表的代码

(define (db_insert rec)
  (set! db (cons rec db))
  (display db)  

  (display "\n There is/are ")
  (display (count))
  (display " record(s) in the database"))
如果它是平等的,这将会返回...我是否正确地假设?但是我该如何继续穿越?

修改 好的,这是我目前的问题。再次,我的名单或"记录"附加到空列表中的格式为(define getName name) [(empty? db) '()] [(equal? (car(car db)) name) (car db)] 。我现在正在尝试编写一个使用(Matthew (AL 21 32))(我重命名为getName)的函数,以便找到所需的记录,然后将记录中的两个数字相乘。但是,我的当前代码只有在我在第一条记录上获取名称时才会运行,但在此之后它会为任何记录返回一个空列表。这是我的代码:

fetchRecord

我该如何解决这个问题?此外,如果某个记录有两组数据,如下所示:(define (Bill_Amt name) (cond [(empty? db) #f] [else (* (car(cdr(car(cdr (fetchRecord name))))) (car(cdr(cdr(car(cdr (fetchRecord name)))))))])) 那么您将如何将其输出'(John (AL 25 40) (CA 40 67))25*40等,即使它超过两组数据?我知道这将是递归,但我不太确定如何设置它,因为40*67car的使用会发生变化。

1 个答案:

答案 0 :(得分:0)

您正在尝试创建和操作字典。在Lisp中,当在列表上实现时,它被称为assoc-list,因为每个条目都可以通过内置函数assoc获得。

也许你打算重新实施它,作为你学习经历的一部分。

首先,由于您标记您的条目具有不同的名称,当您点击您搜索的名称时,您已找到它。据推测,您不会使用相同的名称标记不同的条目。如果您的列表已经用尽,即已到达'()的阶段,那么您就知道搜索已经结束,而您还没有找到您要搜索的内容。

要遍历列表,只需使用car检查其第一个条目,然后使用cdr删除它。

当您获得一个条目时,您可以使用car再次检查第一个元素,即名称。

编写函数时,注意不要使用任何名称 - 使用函数提供的参数。当然要注意括号。

(define (get-name name db)
  (cond
    [(empty? db)                     ; end of list reached --
          #f]                        ;   use #f to signal failure
    [(equal? (car (car db)) name)    ; found entry with same name --
          (car db)]                  ;   return it
    [else (.... name (cdr db))]))    ; else go on working on the rest of the list

另见:cond

对于db-insert,请遵循与遍历相同的代码大纲,并返回更新的关联列表。

(define (db-insert name data db)
  (cond
    [(empty? db)                          ; end of the list
         (list   (cons name .... ))]      ; new entry, name wasn't found
    [(equal? (car (car db)) name)         ; same name found --
         (cons   ....                     ; an updated entry goes here
                 (cdr db))]
    [else                                 ; mismatch -- 
         (cons (car db)                   ;      preserve the current entry, and
               (db-insert name data       ;      go on working
                          (......)))]))   ;      on the rest of the list