【发布时间】:2013-08-13 14:00:41
【问题描述】:
我喜欢创建带有无限数量参数的函数,并且能够将它们作为列表处理。它在创建二叉树时对我很有用,我现在正在使用它来改进最近邻算法。然而,我的方法真的很糟糕:因为我想不出一种方法来遍历不正确的列表(这很可能是不正确的和退化的),我尝试使用各种列表函数将不正确的列表强制转换为列表形式。
这是我在确定地图节点之间差异的简单函数中的最佳尝试(有效,只是不确定为什么有效):
(define distance-between
(lambda xs
(let ([input-list (list* xs null)])
(letrec
([f (lambda (xs acc)
(if (null? (cdr xs))
acc
(f (cdr xs)
(+ (abs (- (map-node-x (car xs))
(map-node-x (cadr xs))))
(abs (- (map-node-y (car xs))
(map-node-y (cadr xs))))
acc))))])
(f (car input-list) 0)))))
如您所见,这是一个丑陋的解决方案,并且涉及一些对我来说似乎很神奇的东西 - 为什么当我将不正确的列表包含在列表中时,它会被强制转换为列表形式*? (注意:这句话具有误导性,这不会发生)。
我宁愿有一个漂亮的解决方案而不是魔法。有人可以帮忙吗?
例如,典型的输入是:
(distance-between (map-node 1 2) (map-node 2 3) (map-node 3 4))
预期结果:
4
(map-node (a) 和 m-n (b) 之间的距离为 2,加上 map-node (b) 和 map-node (c) 之间的距离为 2)。
也可以简单地输入:
(distance-between (map-node 1 2) (map-node 2 2))
并得到答案:
1
如果我在原始输入上尝试此操作,而没有我的 (let ([input-list...])...) 语句,则会导致错误,因为 (? 实际上不确定为什么要回答这个问题) .
函数按预期工作。
【问题讨论】:
-
在什么情况下您可能会处理不正确的列表?可变参数列表总是正确的。此外,您应该使用示例输入和输出来描述您的函数应该做什么。
-
我不确定可变参数列表是什么(也许除了这个)。我的想法是,这些列表不适合堆栈溢出的其他一些答案,以及未处理的列表 xs 不被任何其他函数视为列表的事实 - 他们抛出错误说它不是列表。此外,它不会自动以 null 结尾,我认为所有 Lisps 都将其用作其列表的基础。我将描述我的函数现在做了什么,但它完全按照预期工作。
-
基本上我的困惑源于这样一个事实,即当我尝试在...可变参数列表的原始输入上使用诸如 (length xs) 之类的列表函数时?它们会引发错误。
-
在示例中,问题不在于函数,而在于您调用它的方式。应该是:
(define dist (distance-between (map-node 1 2) (map-node 2 3) (map-node 3 4))) -
糟糕。对不起,那是一个错字。我通常不是这样称呼它的。但是,您完全正确,问题出在其他地方。
标签: list arguments scheme racket variadic-functions