尝试学习 Scheme 的递归问题

Problems with recursion trying to learn Scheme

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

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

我的第一个想法是遍历列表直到找到名称,然后从那里 cdrcar 以获得我需要提取的任何信息; 但是 如果我开始 cdrcar 它最终不会超过那个名字的记录吗?

(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)]

这会 return 如果它相等...我假设正确吗?但是如何继续遍历呢?

编辑 好的,这是我目前的问题。因此,我的列表或 "records" 一起附加到一个空列表中的格式为 (Matthew (AL 21 32))。我现在正在尝试编写一个函数,该函数将使用 getName(我将其重命名为 fetchRecord)以找到所需的记录,然后将记录中的两个数字相乘。但是,我当前的代码 仅当 我在第一条记录上获取名称但它 return 之后的任何记录都是一个空列表时才有效。这是我的代码:

(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*4040*67 等,即使它有超过两组数据?我知道这将是递归,但我不太确定您将如何设置它,因为 carcdr 的用法会改变。

您正在尝试创建和操作字典。在 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,遵循与遍历相同的代码大纲,return 更新 assoc-list。

(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