我需要定义一个lisp函数iscube,它将一个整数作为参数,如果n是一个立方体,则返回T,否则返回nil。
我只知道如何使整数成为一个多维数据集,但是如何确定一个整数就是一个多维数据集?
不允许我使用任何特殊的数学函数,例如log来解决此问题...
示例iscube(8)将返回true,与iscube(-8)将返回true。
答案 0 :(得分:1)
您应该注意到,它似乎还不那么聪明,以至于无法完成您的作业。但是,由于我必须给我一些乐趣,所以可以从这里开始:
(defun is-cube-p (n)
"Returns T if N is a cube number."
(zerop (nth-value 1 (round (abs (expt n 1/3))))))
CL-USER> (is-cube-p -8)
T
CL-USER> (is-cube-p 8)
T
CL-USER> (is-cube-p 9)
NIL
我既不是数学家,也不是CL专业人士,因此无法保证这是解决问题的最佳方法。
答案 1 :(得分:0)
我将提供类似于Martin's的解决方案,它会比较慢。但这对于某些人来说可能更容易理解。
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}?api-version=2018-06-01
这个想法是首先计算n的立方根,然后找到根的整数部分。我们将整数部分立方化回m并比较m和n。如果m == n,则n是一个立方体。
答案 2 :(得分:0)
此页面上的其他一些答案存在浮点精度问题,因此不正确;特别是,expt
可以返回浮点近似值。作为一个 commenter pointed out,这可能导致非立方体的数字被报告为立方体。数字 9,261,000 是一个完全立方体(210 的立方体),但数字 9,261,101 不是一个完全立方体;然而这里的其他三个答案中有两个报告说 9,261,101 是一个完美的立方体。
一个good solution是找到n
的立方根,将其转换为整数,然后将该整数的立方与n
进行比较,避免精度问题。
另一种解决方案是对整数值使用二进制搜索。我在这里包含这个解决方案并不是因为它是最好的解决方案,而是因为记住二进制搜索等基本思想可以被广泛应用是很好的。在您不确定如何处理浮点精度问题的情况下,对整数进行二分搜索可能会得到正确的结果。
(defun cubep (n)
(let ((n (abs n)))
(flet ((midpoint (a b) (truncate (+ a b) 2))
(closep (a b) (< (- b a) 2)))
(labels ((bsearch (start end)
(let* ((mid (midpoint start end))
(mid-cubed (expt mid 3)))
(cond ((closep start end) nil)
((< mid-cubed n)
(bsearch mid end))
((> mid-cubed n)
(bsearch start mid))
(t t)))))
(or (zerop n) ; test ends of search range
(= n 1)
(bsearch 0 n))))))
这里,因为有立方根的非负数对应有立方根的负数,所以只考虑n
的绝对值。搜索 0 到 n
之间的整数,直到找到 n
的立方根,或者直到搜索间隔太小而无法包含另一个整数。
CL-USER> (cubep 8)
T
CL-USER> (cubep -27)
T
CL-USER> (cubep 11)
NIL
CL-USER> (cubep 9261000)
T
CL-USER> (cubep 9261001)
NIL
当数字开始变大时,前面提到的浮点精度问题就会变得明显。这是一个比较两种实现结果的函数:
(defun compare (func1 func2 a b)
(let ((failures (loop for n from a to b
unless (eql (funcall func1 n) (funcall func2 n))
collect n)))
(if (null failures)
(format t "PASSED~%")
(format t "FAILURES: ~A~%" failures))))
这是将cubep
与错误的cube-p
进行比较的结果;由于浮点数处理不当,9,260,000 和 10,000,000 之间的 12 个数字被误报为完美立方体。这些是很大的输入数字,但它们并没有那么大。错误版本的 is-cube-p
结果相同:
CL-USER> (compare #'cubep #'cube-p 9260000 10000000)
FAILURES: (9260999 9261001 9393930 9393932 9528127 9528129 9663596 9663598
9800343 9800345 9938374 9938376)