2

10進数を(-2)adian数値システム(-2の2進数にのみ類似)に変換する2つの関数を作成する必要があり、その逆も同様です。私はすでに小数->(-2)adianを実行することに成功しました。しかし、(-2)adian-> 10進数では問題があり、どこから始めればよいのかわかりません。あなたが私を助けることができることを願っています

type NegaBinary = String

-- Function (-2)adisch --> decimal
negbin_dezi :: NegaBinary -> Integer -> Integer
negbin_dezi (xs:x) n 
    | (x == 0) = if ([xs] == "") then 0 else (negbin_dezi [xs] (n+1))
    | (x == 1) = if ([xs] == "") then (-2)**n else (-2)**n + (negbin_dezi [xs] (n+1))

常に次のようにスローされます: "negbin_deziの定義に必要な(Num [Char]、Floating Integer)のインスタンス。

なぜそれが機能しないのか誰かが考えていますか?お願いします:)

4

3 に答える 3

5

リストのパターンマッチング構文が逆になっています。最初の引数は_ : _リストの先頭(1つの要素)で、2番目の引数はリストの末尾(別のリスト)です。たとえば、 givesx:xsと一致します。だからです。GHCが、を要求する理由は、比較(および)です。この場合、(== )のタイプを()のタイプと一致させようとしています。これを行うには、のインスタンスが必要です。"abc"x = 'a' xs = "bc"xs:xx:xsinstance of Num [Char]x == 0x == 1xString[Char]0Num a => aNumString

修正は次のとおりです。negbin_dezi (x:xs) n

Floating Integerインスタンスを要求する際の問題は、タイプがあり、必要に応じて(**)タイプがあるためです(つまり、整数乗に制限されます)。Floating a => a -> a -> a(^)(Num a, Integral b) => a -> b -> a

これを実行すると、いくつかの理由でアルゴリズムが機能しないことがわかります。

  • 数字の0は文字とは異なります。数字とではなく、文字と'0'比較する必要があります。x'0''1'01
  • xsはすでに文字列であるため、文字[xs]列を含むリストも必要ですが、これは必要なものではありません。これは、角かっこを削除することで修正されます。
  • おそらく、削減の順序が間違っています。

別の注意点として、重複したifステートメントは、コードで発生する可能性のあるいくつかの最適化があることを示唆しています。具体的には、空の文字列をその一部として処理するnegbin_dezi場合、特別な大文字小文字を区別する必要はありません。あなたはそれを次のように書くことができます

negbin_dezi "" _ = 0
negbin_dezi (x:xs) n 
        | n == '0' = negbin_dezi xs (n+1)
        | n == '1' = (-2)^n + negbin_dezi

(これには、関数が「より合計」である、つまり、より多くの入力で定義されるという意味のボーナスがあります。)

さらにいくつか:

  • コードは「文字列型」です。より多くの構造を持っているにもかかわらず、データは文字列として表されています。ブール値([Bool])のリストの方がはるかに優れています。
  • アルゴリズムは、よりクリーンになるように適合させることができます。以下では"01" = -2 "001" = 4、などのように保存していると仮定します。そうであれば、、、、、...が数字であることnumber = a + (-2) * b + (-2)^2 * c ... = a + (-2) * (b + (-2) * (c + ...))がわかります。これを見ると、括弧内のものは実際には式全体と同じであり、2桁目から始まっていることがわかります。これはHaskellで簡単に表現できます(私はブールリストのアイデアを使用しています)。abc

    negbin [] = 0
    negbin (x:xs) = (if x then 1 else 0) + (-2) * negbin xs
    

    そして、それがすべてです。この順序で保存していない場合は、を呼び出してreverse修正してください。(本当にトリッキーなので、書くことができます

    negbin = foldr (\x n -> (if x then 1 else 0) + (-2)*n) 0
    

    )。

于 2012-11-06T21:04:32.630 に答える
3

いくつかの問題:

  1. x == 0またはx == 1ですが、xですChar。つまり、 ですx == '0'

  2. あなたが書く(xs:x)。リストの最後に一致するパターンはありません。おそらく、最初にリストを逆にするヘルパー関数を使用してください。

  3. [xs]には 1 つの要素があり、 になることはありません""。代わりに基本ケースを使用してください。

  4. パターン マッチングは、等価性チェックよりも役立ちます。

  5. **は浮動小数点の累乗^用、 は整数の累乗用

  6. [xs]という意味でよく使用しますxs。リストを作成するために角かっこを入れる必要はありません。

動作する書き換えは次のとおりです。

negbin_dezi1 :: NegaBinary -> Integer
negbin_dezi1 xs = negbin (reverse xs) 0

negbin []     _ = 0
negbin (x:xs) n 
    | x == '0' = negbin xs (n+1)
    | x == '1' = (-2)^n + (negbin xs (n+1))

パターンマッチングを使用する方が良いでしょう:

negbin_dezi2 :: NegaBinary -> Integer
negbin_dezi2 xs = negbin (reverse xs) 0 where
  negbin []     _ = 0
  negbin ('0':xs) n =          negbin xs (n+1)
  negbin ('1':xs) n = (-2)^n + negbin xs (n+1)

しかし、'0' を 0 に、'1' を 1 に変換し、それを乗算する方が良いかもしれません:

val :: Char -> Int
val '0' = 0
val '1' = 1

negbin_dezi3 :: NegaBinary -> Integer
negbin_dezi3 xs = negbin (reverse xs) 0 where
  negbin []     _ = 0
  negbin (x:xs) n = val x * (-2)^n  +  negbin xs (n+1)

ただし、そのようには書きません。

まったく別のアプローチは、すべてを一度に考えることです。

"10010" -rev> [0,1,0,0,1] -means> [  0,      1,      0,      0,      1  ]
                                  [(-2)^0, (-2)^1, (-2)^2, (-2)^3, (-2)^4] 

両方のリストを作りましょう

powers = [(-2)^n | n <- [0..]]
coefficients = reverse.map val $ xs

そしてそれらを掛けます

zipWith (*) powers coefficients

合計すると、次のようになります。

negbin_dezi4 xs = sum $ zipWith (*) powers coefficients
    where powers = [(-2)^n | n <- [0..]]
      coefficients = reverse.map val $ xs

のように書き直すこともできますpowersmap ((-2)^) [0..]、もっとうまく書くこともできます
: powers = 1:map ((-2)*) powers
(以前の計算を再利用し、心地よくクリーンなため、より優れています。)

于 2012-11-06T20:59:06.263 に答える
0

これ

convB2D::NegaBinary->整数
convB2D xs|(長さ xs)==0 =0
          |b=='0' = convB2D(ドロップ 1 xs)
          |b=='1' = val+convB2D(ドロップ 1 xs)
          |otherwise= エラー "無効な文字"
               ここで、b=頭 xs
                       val=(-2)^((長さ xs)-1)

私のために働いた。一方、dec->nbin の変換に問題があります:D

于 2012-11-13T15:27:18.720 に答える