1

Codewars Ruby の問題に取り組んでいますが、表示されているエラーがわかりません。手順は次のとおりです。

階乗による 10 進数のコーディングは、階乗ではなく階乗に依存する基本システムで数値を書き出す方法です。このシステムでは、最後の桁は常に 0 で、基数は 0 です。その前の数字は 0 または 1 で、基数は 1! です。その前の数字は 0、1、または 2 のいずれかで、基数は 2 です。より一般的には、最後から n 番目の数字は常に 0、1、2、...、または n であり、基数は n! です。

例:10 進数の 463 は「341010」とコーディングされます。

なぜなら 463 (基数 10) = 3×5! +4×4!+1×3!+0×2!+1×1!+0×0!

数字 0 ~ 9 に制限されている場合、コード化できる最大の数字は 10 です。- 1.

したがって、0..9 を A から Z の文字で拡張します。これらの 36 桁を使用して、最大 36 までコード化できます。− 1 = 37199332678990121746799944815083519999999910 (基数 10)

2 つの関数をコーディングします。最初の関数は 10 進数をコーディングし、階乗表現の文字列を返します: "dec2FactString(nb)"

2 つ目は階乗表現で文字列をデコードし、10 進数表現を生成します: "factString2Dec(str)"。

与えられた数値は正になります。

ノート

Clojure、Python、Ruby、Haskel では Big Integer を使用したテストを期待できますが、「dec2FactString(nb)」の数値「nb」が最大長である Java などでは期待できません。

参照: http://en.wikipedia.org/wiki/Factorial_number_system

def dec2FactString(nb)
  if nb <= 0 then
    num = 1
  else
    num = (nb * dec2FactString(nb - 1))
  end
  return num
end

この方法は問題の前半に過ぎないことに注意してください。このコードは、このテストを使用すると Fixnum として正しい階乗を返す限り、機能しているように見えます。

Test.assert_equals(dec2FactString(4), "24") 

命令は文字列を要求するので、通常は ".to_s" を num 変数に追加するだけで問題ないと思いますが、代わりに一貫した "String can't be coerced into Fixnum (TypeError)" が表示されます。 " エラーメッセージ。出力を配列にプッシュしてそこから印刷しようとしましたが、同じエラーが発生しました。

私はFixnumを少し読んで、Fixnumを文字列に追加するという点でエラーが機能しないことを理解していますが、この場合はそうしていないと思います-Fixnum出力を変換したいだけです文字列に。何か不足していますか?

観察 - このコードは壊れて、その下にエラーが発生します。

def dec2FactString(nb)
  if nb <= 0 then
    num = 1
  else
    num = (nb * dec2FactString(nb - 1))
  end
  return num.to_s
end

Example from description
 `*': String can't be coerced into Fixnum (TypeError)
    from `dec2FactString'
    from  `dec2FactString'
    from  `dec2FactString'
    from  `dec2FactString'
    from  `block in 
'
    from  `block in describe'
    from  `measure'
    from  `describe'
    from  `
'
4

2 に答える 2

4

この関数を再帰的に呼び出しています。1 の階乗を計算してそのままto_sにしておけば、変数を再利用していないので問題ありません。

しかし、to_sそこに配置した場合、結果はどうなると思いますnum = (nb * dec2FactString(nb - 1))か? の代わりに a をdec2FactString返すことになり、数値と文字列の間で乗算を行うことはできません/できません。strFixnum

あなたができることは、2 つのメソッドを作成することによって、文字列化と計算の責任を分割することです。

def dec2FactString(nb)
    return fact(nb).to_s
end

def fact(nb)
    if nb <= 0 then
        1
    else
        nb * fact(nb - 1)
    end
end
于 2015-08-03T17:59:34.567 に答える
0

まず、階乗は非負の数でのみ定義されるため、最初のテストは正しくありません (nb <= 0 の場合)。再帰は数値が 0 のときに停止し、その時点で 1 を返す必要があります。

再帰は数値ではなく文字列を返すため、次の再帰ラウンドで文字列に Fixnum を掛けることはできません。再帰は、置換メソッドを使用して次のように拡張できます。

dec2FactString(5)
5 * dec2FactString(4)
5 * 4 * dec2FactString(3)
5 * 4 * 3 * dec2FactString(2)
5 * 4 * 3 * 2 * dec2FactString(1)
5 * 4 * 3 * 2 * 1 * dec2FactString(0)
5 * 4 * 3 * 2 * 1 * "1"

... dec2FactString(0) が「1」を返すため、再帰がエラーで終了するポイントです。

2 つの機能に分割する方がはるかに優れています。階乗を再帰的に計算するものと、最終的な答えを文字列に変換するものです。また、Ruby では明示的に値を返す必要はありません。関数の最後の行は戻り値です。

何も学べないので、完全なコードは提供しません。いくつかのヒントとして、Ruby の末尾呼び出しの最適化、再帰、および戻り値について調査してください。これにより、再帰関数のより良い実装を作成できます。

ハッピーコーディング!

于 2015-08-03T19:49:11.253 に答える