Haskell比较问题

时间:2017-03-24 14:20:57

标签: haskell

我使用递归来比较两个数字(ex 123与123相同)并存储它们共有多少个数字(ex 123与123相比有3个而124有2个)。

虽然我的程序确实找到了这个数字,我想为每种情况设置条件(例如,如果它们在共同的输出值44中有2位数,或者如果它们有3则执行其他操作等),但是没有进行比较。有人可以向我解释是什么以及为什么会发生这种情况。这是我的代码:

dg :: Int->Int->Int  
dg 0 0 = 0
dg x y = if (c==2) then 23 else 24 -- c = common digits
    where c = digits (x `div` 10) (y `div` 10) + if (x `mod` 10 == y `mod` 10) then 1 else 0        

我喜欢删除"如果"条件,给输入10 10输出是2但是当我把它打开并重新运行时,它变为24(而23是正确的)。我真的很困惑。

1 个答案:

答案 0 :(得分:1)

要查找两个Int共有多少位数,使用字符串表示并不太糟糕(实际上很糟糕,请参阅下面的更新

commonDigits :: Int -> Int -> Int
commonDigits a b = length . filter id $ zipWith (==) (reverse $ show a) (reverse $ show b)

reverse需要确保数字正确对齐。

如果你是无点风格:

import Data.Function

commonDigits :: Int -> Int -> Int
commonDigits = fmap (length . filter id) . zipWith (==) `on` reverse . show

然后,如果您想根据Int的结果返回特殊commonDigits,则可以使用单独的函数:

specialResult :: Int -> Int -> Int
specialResult a b =
  case commonDigits a b of
    2 -> 23
    3 -> 48
    _ -> 256

更新:对于负整数,此方​​法并不好。如果只有一个参数为负数,则此函数的行为应与 mod 10 版本相同。如果两者都为负数,则“ - ”符号可能被计为数字。

让我们使用digits函数,该函数将给出从最低有效数字到最高有效数字的正数和负数的数字列表。如果输入数字0会发生什么,我们应该返回一个空列表还是[0]?你打电话给那个,但我假设你想要[0]

digits :: Int -> [Int]
digits 0 = [0]
digits n = digits' (abs n)
  where
    digits' 0 = []
    digits' n = n `mod` 10 : digits' (n `div` 10)

使用这个新的digits函数,我们可以将commonDigits重写为:

commonDigits :: Int -> Int -> Int
commonDigits = fmap (length . filter id) . zipWith (==) `on` digits