gpt4 book ai didi

if-statement - 新 Racket : why is the if statement affecting the return?

转载 作者:行者123 更新时间:2023-12-04 05:14:58 28 4
gpt4 key购买 nike

我刚开始学习 Racket,所以我仍在努力弄清楚这门语言的复杂性。我正在尝试在列表中实现我自己的搜索功能。如果函数找到它,则返回索引,否则返回 -1。

(define (find-index list item)
(if (equal? (length list) 1)
(if (equal? (first list) item) 0 1)
(if (equal? (first list) item)
0
(+ 1 (my-search (rest list) item)))))

所以 find-index 函数是一个递归函数,它遍历列表以寻找与“item”等价的项目。我这样写,如果列表中有 4 个元素,该函数可以返回 0-4 之间的任何数字。

(define (my-search list item)
(define length (my-length list))
(define index (find-index list item))
(if (= index length) -1 index))

我的想法是,如果 find-index 函数返回一个等于列表长度的数字,则意味着函数没有找到该项目,因此 my-search 函数应该返回 -1。

但是,当我输入

(my-search (list "apple" "barbecue" "child" "demon" "enter") "fire")

我得到的结果是 3,而不是 -1。如果我在 if 语句之前打印索引,则索引为 3 而不是 5。如果

(if (= index length) -1 index))

不是我的搜索功能的一部分,那么一切都很好。

我认为发生的事情是索引是函数本身的 id,而不是函数的结果。但是,我不明白为什么这会影响我的搜索的返回结果。有人愿意阐明这个问题吗?

此外,欢迎任何风格评论。我想知道我是否没有遵守约定。

最佳答案

奇怪的行为是由于 find-index 调用 my-search 而调用 find-index (相互的递归!)。在某些时候,额外的 if 会导致递归过早结束。解决方案:在 find-index 过程中将对 my-search 的调用替换为 find-index

既然已经解决了,我们可以编写一个过程来查找列表中元素的索引或发出未找到该元素的信号,如下所示:

(define (find-index lst item)
(cond ((empty? lst) #f)
((equal? (first lst) item) 0)
(else
(let ((result (find-index (rest lst) item)))
(if result (add1 result) #f)))))

让我们看看以上内容如何改进您的程序:

  • 构造具有多个条件的过程的首选方法是使用 cond
  • 你不应该使用 list 作为参数名,它与同名的内置过程冲突
  • 出于同样的原因,你不应该称length为局部定义
  • 使用length 来检查我们是否超出列表不是一个好主意,构建良好的递归将解决这个问题,而不必重新遍历列表
  • 通常使用 #f 来表示搜索过程没有找到它要查找的内容
  • 在结构良好的列表递归中,您应该检查列表是否为空,通常这是我们编写的第一个基本情况 - 如果传递空列表,您的过程将失败
  • 我们使用 let 来声明局部变量,在这种情况下它是有意义的,以避免调用递归两次
  • 使用(add1 x),它比(+ 1 x)更加地道

但是等等,我们可以做得更好!可以用尾递归 风格重写上述解决方案;通过确保递归调用是我们做的最后一件事,我们的过程将使用常量空间,并且它将与传统编程语言中的循环一样高效。诀窍是传递一个带有要返回值的额外参数(在本例中为索引)。为简洁起见,我将使用命名的 let:

(define (find-index lst item)
(let loop ((lst lst) (idx 0))
(cond ((empty? lst) #f)
((equal? (first lst) item) idx)
(else (loop (rest lst) (add1 idx))))))

您可以验证这两个过程是否如宣传的那样工作:

(find-index (list "apple" "barbecue" "child" "demon" "enter") "fire")
=> #f
(find-index (list "apple" "barbecue" "child" "demon" "enter") "child")
=> 2

关于if-statement - 新 Racket : why is the if statement affecting the return?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39339604/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com