Recursion 将递归生成的列表返回到Lisp中的调用函数时出现问题
我是Lisp新手,对递归和函数返回有疑问。为了更好地理解和解决我的问题,我提供以下场景。如果是冗长的,我道歉。如果这激怒了其他人,我很乐意减少它。若要直接跳到业务,请从水平线开始阅读 想象一下酒吧里的女服务员。她强迫顾客自称是啤酒、朗姆酒、威士忌或这些饮料的混合饮料的饮用者,而不是点饮料。然后,她抓起一个装满啤酒、朗姆酒或威士忌的托盘,绕着酒吧转了一圈,只留下一杯饮料给任何一位确认自己是该饮料饮用者的顾客。每次结束后,她都会坐下来喝一杯长岛冰茶。之后,她继续抓起另一盘专门的一种饮料,再次出去送货。没有顾客可以拒绝一杯饮料,也没有人可以改变他们的饮料偏好 现在,Mindy(女服务员)需要一种新颖的方法来记录她为每位顾客提供的每种饮料的数量。明蒂的数学不是很好,到了晚上,所有长岛冰茶的数量都在增加 因此,当她要求一个简单的解决方案来跟踪她的饮料分配时,我自然建议创建一个简单的Lisp小程序。工作原理如下:当Mindy完成一轮美味饮料后,她只需走到她的Altair 8800并键入以下内容:Recursion 将递归生成的列表返回到Lisp中的调用函数时出现问题,recursion,lisp,clisp,Recursion,Lisp,Clisp,我是Lisp新手,对递归和函数返回有疑问。为了更好地理解和解决我的问题,我提供以下场景。如果是冗长的,我道歉。如果这激怒了其他人,我很乐意减少它。若要直接跳到业务,请从水平线开始阅读 想象一下酒吧里的女服务员。她强迫顾客自称是啤酒、朗姆酒、威士忌或这些饮料的混合饮料的饮用者,而不是点饮料。然后,她抓起一个装满啤酒、朗姆酒或威士忌的托盘,绕着酒吧转了一圈,只留下一杯饮料给任何一位确认自己是该饮料饮用者的顾客。每次结束后,她都会坐下来喝一杯长岛冰茶。之后,她继续抓起另一盘专门的一种饮料,再次出去送货
(update-orders <order-list> <drink>)
相反,我希望列表的格式与上面提供给函数的格式相同
请参阅下面的代码。为方便起见,已对其进行了修改,将调试输出包括在屏幕中。功能饮料清单可能是我的麻烦所在
(defun update-orders (x d)
(print 'orders)
(prin1 x)
(order (car x) d)
)
(defun order (x d)
(print 'order)
(prin1 x)
(drink-list (cdr x) d)
)
(defun drink-list (x d)
(print 'drink-list)
(prin1 x)
;(append
;(cons
;(list
(drink-count (car x) d)
(cond
((cdr x) (drink-list (cdr x) d))
(t x)
)
;)
)
(defun drink-count (x d)
(print 'drink-count)
(prin1 x)
(list
(cond
((eq (car (cdr x)) d)
(modify-count (car x) 1))
(t x)
)
)
)
(defun modify-count (x d)
(print 'modify-count)
(prin1 x)
(print 'new-modify-count)
(prin1 (+ (parse-integer (subseq (write-to-string x) 0)) 1))
(list
(+ (parse-integer (subseq (write-to-string x) 0)) 1)
)
)
编辑:
我已经将ooga的建议合并到我的代码中。新订单和更新订单功能如下所示:
(defun update-orders (x d)
(cond
((null x) ())
(t (cons (order (car x) d) (update-orders (cdr x) d)))
)
)
(defun order (x d)
;(print 'order)
;(prin1 x)
(drink-list (cdr x) d)
)
现在返回以下列表,运行与上面相同的函数调用:
((5杯威士忌))((1杯啤酒))((4杯朗姆酒))((2杯朗姆酒)))
这是一个嵌入列表的列表(我相信有两个深度),包括列表中所有最后的饮料项目和每位顾客的饮料数量(比尔的最终列表条目是5杯威士忌,吉姆的最终条目是1杯啤酒,等等)。他们的第一批n-1饮料不会添加到他们的饮料返回列表中
我误解了你的建议吗?我有一种感觉,我离这里只有半步之遥。在更新订单中,您只需将x的车交给订单即可。x的其余部分完全被忽略。然后,您只传递“要喝的饮料”列表上的cdr 下面是一个程序,它向给定列表的每个成员添加1,以说明代码的结构 调用示例:
(增量列表(1233))
将增量列表
更改为更新订单
,将增量
更改为订单
(并添加第二个输入等),我认为这应该是您的程序结构
此外,您应该尝试从下往上构建它。尝试编写一个函数,如果(数字饮料)列表中的给定饮料匹配,该函数将向数字中添加一个。即,鉴于此:
(add-one-if '(4 beer) 'beer)
它应该归还这个
(5 BEER)
(3 WHISKEY)
鉴于此
(add-one-if '(3 whiskey) 'beer)
它应该归还这个
(5 BEER)
(3 WHISKEY)
正如上面所建议的,下面是我为解决我的问题而实现的完整代码,包含了ooga提供的建议结构
;;;; WAITING-TABLES
(defun update-orders (x d)
(cond
((null x) ())
(t (cons (order (car x) d) (update-orders (cdr x) d)))
)
)
(defun order (x d)
(cons (car x) (drink-list (cdr x) d))
)
(defun drink-list (x d)
(cond
((null x) ())
(t (cons (drink-count (car x) d) (drink-list (cdr x) d)))
)
)
(defun drink-count (x d)
(cond
((eq (car (cdr x)) d)
(cons (modify-count (car x) 1) (drink-count (cdr x) d)))
(t x)
)
)
(defun modify-count (x d)
(+ (parse-integer (subseq (write-to-string x) 0)) 1)
)
“
(更新订单(订单列表饮料))
其中,订单列表
是所有客户及其订单的列表,“饮料”是她最近一次外出时刚供应的饮料。”如果订单列表
是一个列表,您可能指的是(更新订单列表饮料)
,对吗?我当然这么做了,先生。我会修改。我注意到在Lisp中有这样一种极端的倾向。也许是我的Java背景?也谢谢你的其他捕获。我已经编辑了我的帖子,包括你建议的更改。进展,但不完全。也许我误解了什么。谢谢!这让我离开了屏幕几米在充分理解cons参数的工作原理后,我将您的建议纳入了另外两个函数中。这100%解决了我的问题,我终于感觉我理解了Lisp的这一方面(以及一般的编程)完全。非常感谢,先生。太好了!很高兴能提供帮助。如果您愿意,请将您的解决方案发布为“答案”(您可以发布您自己问题的答案),我会看一看。这看起来很好。我唯一能看到的(可能是我错了)是,饮料计数和修改计数可以替换为(defun drink count(x d)(cond((eq(car(cdr x))d)(cons(+(car x)1)(cdr x)))(tx)))
谢谢。我也会在我的作业中使用这个修改,这是一个基于这个相关示例的更复杂的程序。应该也会为我节省一些不动产。干杯!