【问题标题】:What's wrong with this Prime-testing function?这个 Prime 测试功能有什么问题?
【发布时间】:2018-01-20 01:19:40
【问题描述】:

我几乎到处寻找,但找不到以下代码不起作用的原因:

isPrime :: Int -> Bool
isPrime 1 = False
isPrime n = divTest n (floor (sqrt n))
    where
    divTest :: Int -> Int -> Bool
    divTest n test
        | test == 1         = True
        | mod n test == 0   = False
        | otherwise         = divTest n (test-1)

我得到了两个错误,它们真的很长,所以我将把我认为重要的部分放在:

No instance for (RealFrac Int) arising from a use of ‘floor’

No instance for (Floating Int) arising from a use of ‘sqrt’

是的,我知道这可能没有任何效率。我在学。

【问题讨论】:

    标签: haskell primes


    【解决方案1】:

    sqrt 需要浮点数 - 试试

    isPrime n = divTest n (floor (sqrt (fromIntegral  n)))
    

    【讨论】:

    【解决方案2】:

    计算平方根的另一种方法是计算商余数,并在商小于除数时停止。

    -- Work our way up from 3, testing odd divisors only.
    divTest :: Int -> Int -> Bool
    divTest n test | r == 0 = False
                   | q < test = True -- test > sqrt n, and we've tested all the smaller divisors
                   | otherwise = divTest n (test + 2)
    
    isPrime :: Int -> Bool
    isPrime 1 = False
    isPrime 2 = True
    isPrime n = n `mod` 2 /= 0 && divTest n 3
    

    【讨论】:

      【解决方案3】:

      由于sqrt 的类型为:Floating a =&gt; a -&gt; a,因此您需要传递浮点数而不是整数。您可以通过将fromIntegral 应用于n 来做到这一点,如另一个答案所示。

      解决此问题的另一种方法是将其分解为两个函数。

      第一个函数可以找到直到n的所有因子:

      factors :: Integer -> [Integer]
      factors n = filter divides_n [1..n]
          where divides_n m = n `mod` m == 0
      

      其工作原理如下:

      *Main> factors 15
      [1,3,5,15]
      

      然后我们可以使用它来检查一个数字是否是素数,如果factors 只包含1n

      isPrime :: Integer -> Bool
      isPrime n = factors n == [1,n]
      

      按预期工作:

      *Main> isPrime 2
      True
      *Main> isPrime 3
      True
      *Main> isPrime 4
      False
      *Main> isPrime 5
      True
      *Main> isPrime 15
      False
      

      这种方法的好处是您不必做任何棘手的事情来测试一个数字是否为素数。

      【讨论】:

      • 对于大数字,这要贵一些,但它当然会起作用。
      • 是的,好点。我只是想为 OP 提出一个简单的方法。
      猜你喜欢
      • 2012-07-11
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-10
      相关资源
      最近更新 更多