检查数字是否包含所有数字

时间:2015-03-17 17:21:22

标签: haskell

有效的检查方法是什么,数字是否包含Haskell中的所有数字?修改列表非常低效,因此保留每个数字的出现次数列表是不可行的。你可以在递归中保留10个Bool变量,你可以在其中查看数字的数字列表,但这看起来太难看了。

3 个答案:

答案 0 :(得分:6)

我提出的解决方案比user2407038's快得多。

import Data.Bits
import Data.Char
import Data.List

hasAll10Digits = any (==1023) . scanl setBit (0::Int) . map digitToInt . show

ghci中,它在0.03秒内运行hasAll10Digits(12 ^ 223451)。

相比之下,user2407038的代码在大约11秒内运行。

答案 1 :(得分:3)

这是基于No_signal的excellent approach,但在不分配任何不必要的结构的情况下运行一些小优化。为了实现这一目标,请使用-fllvm进行编译 - GHC的本机代码生成器并不能很好地通过已知除数来优化除法。

hasAllDigits :: Int -> Bool
hasAllDigits = go 0x3FF where
 go !_set 0 = False
 go set n = case (clearBit set r) of
    0    -> True
    set' -> go set' q
   where
     (q,r) = n `quotRem` 10

答案 2 :(得分:1)

没有理由为您的目的列出一个非常低效的列表。您可以使用一组来跟踪您看到的数字。

import Data.List 
import qualified Data.Set as S

digits = foldr S.insert S.empty . unfoldr go where 
  go 0 = Nothing 
  go n = let (a,b) = n `divMod` 10 in Just (b,a) 

hasAll10Digits = (== (S.fromList [0..9])) . digits
insert的{​​{1}}是O(log n),但是您插入的集合将永远不会超过10个元素,因此这些插入基本上是恒定的时间。