【问题标题】:Even number of 2s in prime factorization of number数的素数分解中的偶数 2
【发布时间】:2018-01-29 03:28:05
【问题描述】:

我正在做一个 Haskell 练习题,其中涉及编写一个函数,如果 2 将偶数次除以参数 num,则该函数返回 true。例如,如果 num 是奇数,则返回 True,因为 2 除以 0 次,而 0 是偶数。 8 作为参数返回 False,因为 2 分为 3 次,而 3 是奇数。 我知道如何使用两个参数来解决这个问题,其中第二个参数是一个计数器,并且你将第一个参数除以 2 直到等于 1,如果计数器 mod 2 == 0,则返回 True。但是我们应该只用一个数字作为参数来做到这一点,......那我该怎么做呢? 我的功能,

isGreen :: Int -> Int -> Bool
isGreen num count
    | (num==1)&&(count `mod` 2 == 0) = True
    | (num==1)&&(count `mod` 2 /= 0) = False
    | otherwise = isGreen (div num 2) (count + 1)

【问题讨论】:

  • 你甚至可以直接用countTrailingZeros来判断,是不是在这个问题的范围内?
  • @chepner 8=2^3,8能被4整除,但不是绿色数

标签: haskell recursion


【解决方案1】:

您可以使用异或函数来做到这一点。我不相信这被纳入 Haskell,所以你可以自己做一个

xor :: Bool -> Bool -> Bool
xor True True = False
xor True False = True
xor False True = True
xor False False = False

isGreen :: Int -> Bool
isGreen num
    | (num < 0) = isGreen (-num)
    | (mod num 2 /= 0) = True
    | num > 1 = xor True (isGreen (div num 2))
    | num == 1 = True

之所以有效,是因为每次我们爬回调用堆栈时,我们都会在 True 和 False 之间切换。

Example: isGreen 8 =
xor True (isGreen 4) = 
xor True (xor True (isGreen 2) =
xor True (xor True (xor True isGreen 1)) = 
xor True (xor True (xor True True)) = 
xor True (xor True False) = xor True (True) = 
False

【讨论】:

  • xor 只是/=
  • 你只使用xor 来代替xor True,也就是not
【解决方案2】:

请注意,您的版本没有给出奇数的正确答案:

> isGreen 0 3
False
>

因为它在应该使用 odd n 代替时使用 n == 1 检查终止。

无论如何,作为替代方案,您可以通过观察如果x 可被4 整除,则isGreen xisGreen (x `quot` 4) 相同,从而构造一个直接递归定义。否则,被 2 整除会给出答案:

isGreen x | x == 0         = error "zero is neither green nor not green"
          | x `rem` 4 == 0 = isGreen (x `quot` 4)
          | even x         = False  -- one two left over
          | otherwise      = True   -- no twos left over

给予:

> map isGreen [1..10]
[True,False,True,True,True,False,True,False,True,False]
>

附带说明一下,出于习惯,我在这里使用了quotrem。至少在英特尔架构和使用原始整数类型时,当您不关心结果的符号时,它们比 divmod 快,所以我在测试可分性时有点习惯使用它们.同样,有些人可能会将第二种情况写为:

| let (q,r) = x `quotRem` 4, r == 0 = isGreen q

基于单个 quotRem 调用将节省单独的 remquot 调用的划分。诚然,这两种优化在这里都相当愚蠢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2014-11-10
    • 1970-01-01
    相关资源
    最近更新 更多