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

ここには 2 つの別個の問題があります。すべての用語書き換え手順を書き出して、それらが何であるかを確認してください。

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

これにより、問題の 1 つが明確に示されます。他のものがまだ表示されていない場合は、次から始めてみてください

sqr 10 3
于 2013-10-29T01:09:45.133 に答える