0

这就是问题所在:声明类型并定义一个函数,该函数将 2 个正数(例如 m 和 n)作为输入,并将 m 提高到 n 次方。请仅使用递归。不要使用幂运算符或库函数,只需使用递归。

到目前为止,这是我的代码:

sqr :: Int -> Int -> Int

平方米

   | m > 0 && n > 0   = sqr (m * m) (n - 1)
   | otherwise        = m

出于某种原因,当我执行 sqr 10 2 时,它给了我 1000 之类的值。有谁知道我做错了什么?

4

2 回答 2

5

让我们展开。此外,您的函数应该被调用pow,而不是sqr,但这并不重要。

sqr 10 2 = sqr (10 * 10) (2 - 1)
         = sqr 100 1
         = sqr (100 * 100) (1 - 1)
         = sqr 10000 0
         = 10000

这说明了为什么sqr 10 2 = 10000

每次递归时, 都有不同的值m。所以你需要以某种方式考虑到这一点:

  1. 要么你编写一个即使m每次都有不同的值也能工作的版本,或者,

  2. 你找到一种方法来保持原来的值m左右。

我想说最简单的方法是使用m^n = m * m^(n-1), 和m^0 = 1.

如果你很聪明,有一种方法更快,它也依赖于m^2n = (m^n)^2.

剧透

我上面写的一些数学公式实际上是有效的 Haskell 代码。

import Prelude hiding ((^))
infixr 8 ^
(^) :: Int -> Int -> Int
-- Do these two lines look familiar?
m^0 = 1
m^n = m * m^(n-1)

这只是函数的中缀版本。您可以将中缀运算符更改为普通函数,

pow :: Int -> Int -> Int
pow m 0 = 1
pow m n = m * pow m (n - 1)

还有更快的版本:

pow :: Int -> Int -> Int
pow m 0 = 1
pow m n
  | even n = x * x where x = pow m (n `quot` 2)
  | otherwise = m * pow m (n - 1)
于 2013-10-29T01:10:00.903 回答
4

这里有两个单独的问题。只需写出所有术语重写步骤,看看它们是什么:

sqr 10 2
sqr (10 * 10) (2 - 1)
sqr 100 (2 - 1)
sqr 100 1
sqr (100 * 100) (1 - 1)
sqr 10000 (1 - 1)
sqr 10000 0
10000

这将清楚地向您显示其中一个问题。如果您还没有看到另一个,请尝试从

sqr 10 3
于 2013-10-29T01:09:45.133 回答