0

タイトルが悪くてすみません…

だから私の問題は、私がこのコードを得たことです:

asd (a:as) (b:bs)= tail(rox(tail(rox (tail (rox (a:as) (b:bs))) (b:bs))) (b:bs))
rox [] as = as
rox as [] = as
rox (a:as) (b:bs) = map abs (a-b:rox as bs)

私のタイプは次のとおりです。asd :: [Int]->[Int]->[Int]

良い解決策を見つけるのに半日を費やしましたが、それしか考えられないので、誰かが私を助けてくれたらとても嬉しいです. (a:as)list から (b:bs)list を減算したいのですが、この後、最初の数値を削除し、result(result-(b:bs)) を取得するまでもう一度やり直します。 (長さ (b:bs))-1) リスト。(a:as)/結果が (b:bs) より低い場合、たとえば 00101<10011 すべての (b:bs) 数値を 0 に変更する必要があります (結果が再び高い場合は、 (b:bs))。例は上記のコードで正常に動作していますが、任意のリストで使用したいと考えています。繰り返し機能を使用する必要があるかもしれませんが、その方法を理解できませんでした。

次に例を示します。

11010(a:as)
101(b:bs)
01110(result)
 1110(after using tail)
 101(b:bs again)
 0100(result)
  100(after tail)
  101(b:bs)
  001(result)
   01(final result after using tail, so its 1number shorter than the (b:bs) list

手伝ってくれてどうもありがとう!

編集:これでどの2進数が大きいかを確認できるので、これですべてのbs番号を0に変えることができますが、実装方法がわかりません。

(%>=%) :: [Int] -> [Int] -> Bool
(%>=%) [] [] = True
(%>=%) as [] = True
(%>=%) [] bs = False
(%>=%) as bs
    | filter (/=0) (takeWhile (>(-1))(ro as bs))==[]=False
    | elem 1 (takeWhile (>(-1))(ro as bs))==True=True

ro :: [Int] -> [Int] -> [Int]
ro []       bs       = bs
ro as       []       = as
ro (a:as) (b:bs) = (2*a) - b: ro as bs

結果:

asd [1,1,1,0,0,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,1,1,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [1,1,1,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,0,1,1,0,0,0,0] [1,1,0,1,1]
asd [1,0,1,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,1,0,0,0,0] [1,1,0,1,1] < here is something wrong because its: 1,1,0,1,0,0,0 and from here everything is wrong
asd [1,1,0,0,0,0] [1,1,0,1,1]
asd [1,0,0,0,0] [1,1,0,1,1]
asd [0,0,0,0] [1,1,0,1,1]
[0,0,0,0]
4

1 に答える 1

2

rem剰余( modulo に似ています)関数を実装しようとしているようですmodが、バイナリリスト用です。Integerリストを に変換して実行すると、はるかに高速になりますrem

まず、バイナリから に変換する関数Integer:

unbinary :: [Int] -> Integer
unbinary = foldl (\ a b -> a * 2 + fromIntegral b) 0

Integer次に、をバイナリに変換する関数:

binary :: Integer -> [Int]
binary = reverse . go
  where
    go 0 = []
    go d =
      let (q, r) = quotRem d 2
      in fromIntegral r : binary q

最後に、remバイナリ リストを処理する関数:

remBinary :: [Int] -> [Int] -> [Int]
remBinary a b = binary $ inta `rem` intb
  where
    inta = unbinary a
    intb = unbinary b

このソリューションの「美しさ」は、2 を任意の数字 (3、6、13 など) に置き換えることができ、バイナリだけでなく、任意のベースで機能することです。


元の質問に答えるには:

これは確かに非常に奇妙な関数であり、私は使用しませんiterate

asd :: [Int] -> [Int] -> [Int]
-- If there is nothing to subtract, let's assume that we should return as
asd as [] = as
asd as bs
  -- If the length of `as` is shorter than `bs`, we are done.
  | length as < length bs
  = as
  | head as == 0
  = asd (tail as) bs
  -- Otherwise, compute `rox as bs`, take its `tail`, and call `asd` recursively
  | otherwise
  = asd (tail (rox as bs)) bs

-- I simplified your version of this function a bit
rox :: [Int] -> [Int] -> [Int]
rox []       bs       = bs
rox as       []       = as
rox (a : as) (b : bs) = abs (a - b) : rox as bs

の最後の部分は、次のasdように書くこともできます。

  = let diff = rox as bs
        tailOfDiff = tail diff
    in asd tailOfDiff bs

そうすれば、あなたの説明により忠実に従います。

于 2012-05-05T23:47:06.317 に答える