尝试学习 Scheme 的递归问题
Problems with recursion trying to learn Scheme
我创建了一个函数,可以将列表插入到定义的空列表中。我插入的列表将有某种类型的关键字来查找它(例如可能是名称或位置),然后是一个嵌套列表,其中包含某种信息,例如通话记录的年龄或其他内容(同样是这个只是我在尝试学习递归语法)。我的问题在于如何
遍历更大的列表并
让程序知道在一个更大的列表中有几个列表,以及如何区分它们。
例如,如果我使用我的函数将 '(John (AL 25 40 67) (CA 40 67 24))
的列表添加到一个空列表,然后 然后 我用不同的名称添加另一个类似的列表比如'(Sue (AZ 45 6 78))
,我怎么告诉它这本质上是存储在同一个名字下的两条不同的记录。
我的第一个想法是遍历列表直到找到名称,然后从那里 cdr
和 car
以获得我需要提取的任何信息; 但是 如果我开始 cdr
和 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)]
这会 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*40
和 40*67
等,即使它有超过两组数据?我知道这将是递归,但我不太确定您将如何设置它,因为 car
和 cdr
的用法会改变。
您正在尝试创建和操作字典。在 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
我创建了一个函数,可以将列表插入到定义的空列表中。我插入的列表将有某种类型的关键字来查找它(例如可能是名称或位置),然后是一个嵌套列表,其中包含某种信息,例如通话记录的年龄或其他内容(同样是这个只是我在尝试学习递归语法)。我的问题在于如何
遍历更大的列表并
让程序知道在一个更大的列表中有几个列表,以及如何区分它们。
例如,如果我使用我的函数将 '(John (AL 25 40 67) (CA 40 67 24))
的列表添加到一个空列表,然后 然后 我用不同的名称添加另一个类似的列表比如'(Sue (AZ 45 6 78))
,我怎么告诉它这本质上是存储在同一个名字下的两条不同的记录。
我的第一个想法是遍历列表直到找到名称,然后从那里 cdr
和 car
以获得我需要提取的任何信息; 但是 如果我开始 cdr
和 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)]
这会 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*40
和 40*67
等,即使它有超过两组数据?我知道这将是递归,但我不太确定您将如何设置它,因为 car
和 cdr
的用法会改变。
您正在尝试创建和操作字典。在 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