尝试学习Scheme的递归问题 [英] Problems with recursion trying to learn Scheme

查看:78
本文介绍了尝试学习Scheme的递归问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个函数,该函数会将列表插入已定义的空列表.我要插入的列表将具有某种类型的关键字(例如名称或位置)来查找它,其后是一个嵌套列表,其中将包含某种信息,例如通话记录的年龄或其他信息(再次如此)只是我尝试学习递归语法).我的问题在于我如何

I have created a function that will insert a list into a defined emtpy list. The list that I am inserting will have some type of keyword for finding it (for example maybe a name or a location) followed by a nested list that will contain some sort of information such as an age of a call record or something (again this is just me trying to learn the recursive syntax). My problem lies in how do I

  • 遍历更大的列表,然后

  • traverse through the bigger list and

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

let the program know that there are several lists within a bigger list and how to differentiate between them.

例如,如果我使用函数将'(John (AL 25 40 67) (CA 40 67 24))的列表添加到空列表,然后然后我以不同的名称(例如'(Sue (AZ 45 6 78)))添加另一个类似的列表,我告诉他们,这些实际上是在一个名称下存储的两个不同的记录.

For example, if I use my function to add a list that is '(John (AL 25 40 67) (CA 40 67 24)) to an empty list, and then I add another similar list under a different name such as '(Sue (AZ 45 6 78)), how do I tell it that these are essentially two different records stored under a name.

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

My first thought process was to traverse the list until it finds the name and then from there cdr and car in order to get to whatever info I needed to pull; but if I start to cdr and car wouldn't it eventually go past that name's record?

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

如果相等,它将返回...我是否正确假设?但是如何继续遍历呢?

this would return if it is equal... Do I assume correctly? But how do I keep traversing?

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

EDIT Okay, This is my current problem. So again my lists or "records" that are appended together into an empty list are in the format (Matthew (AL 21 32)). I am now trying to write a function that would use the getName (I renamed it fetchRecord) in order to find the desired record and then multiply the two numbers inside the record. However, my current code works only if I am getting the name on the first record but it returns an empty list for any record after that. Here is my code:

(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的用法会发生变化,因此不确定如何设置它.

How would I fix this? Also if a certain record has two sets of data like so: '(John (AL 25 40) (CA 40 67)) then how would you go about getting it to output both 25*40 and 40*67 etc., and even if it has more than two sets of data? I understand that it would be recursion but am not quite sure how you would set it up since the usage of car and cdr would change.

推荐答案

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

You are trying to create and manipulate a dictionary. In Lisp, when implemented on lists, it is known as assoc-list, for each entry can be gotten to by means of the built-in function assoc.

作为您学习经验的一部分,也许您打算重新实现它.

Perhaps you intend to re-implement it, as part of your learning experience.

首先,由于您使用不同的名称​​标记条目,因此当您点击要搜索的名称时,便找到了它.大概,您不会用相同的名称标记不同的条目.当您用尽列表(即到达'()的阶段)时,您就知道搜索已经结束,并且没有找到要搜索的内容.

First, since you tag your entries with different names, when you hit the name you search for, you've found it. Presumably, you wouldn't tag different entries with the same name. When you have exhausted your list, i.e. gotten to the stage where it is '(), then you know that your search has ended, and you haven't found what you were searching for.

要遍历列表,只需使用car检查其第一项,然后使用cdr删除它.

To traverse the list, you just use car, to inspect its first entry, and cdr to get rid of it.

掌握条目后,可以再次使用car检查第一个元素,即名称.

When you get hold of an entry, you can inspect its first element, the name, again by using car.

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

When writing functions, pay attention to not use any names out of the blue -- use what arguments your function was supplied with. And of course pay attention to parentheses.

(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

另请参见:

See also: cond.

对于db-insert,遵循与遍历相同的代码大纲,并返回 updated assoc-list.

As for db-insert, follow the same code outline as for traversal, and return the updated 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

这篇关于尝试学习Scheme的递归问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆