有效的检查方法是什么,数字是否包含Haskell中的所有数字?修改列表非常低效,因此保留每个数字的出现次数列表是不可行的。你可以在递归中保留10个Bool变量,你可以在其中查看数字的数字列表,但这看起来太难看了。
答案 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个元素,因此这些插入基本上是恒定的时间。