Haskell:从排序列表中找到k个缺失的数字[1..n]

时间:2016-10-25 19:42:43

标签: algorithm haskell

我正在学习Haskell和FP,并认为这是一个有趣的尝试和解决的问题。我尝试的算法是使用quickselect的变体来计算在枢轴上分割的两个子列表的长度,如果长度差异是1,则使用sums方法的差异来找到缺失的数字。如果大于1,那么我递归地钻入子列表。

我觉得我在这里非常接近一个有效的解决方案,但有一些边缘情况似乎不能很好地运作。在n小于100的情况下,我有时会看到某些丢失的数字,这些数字似乎是随机丢失的,当n与k缺失的数字相比足够小时,我有时会得到运行时异常。对于大的n组,这看似正确。我必须遗漏一些简单的东西。

有什么想法?我错过了一个简单的守卫?

findMissingNumber :: (Ord k, Integral k, Enum k) => [k] -> [k]
findMissingNumber [] = []
findMissingNumber xs = ( sum' [(head xs)..(last xs)] - sum' xs ) : []


findMissingNumbs :: [Int] -> [Int]
findMissingNumbs [] = []
findMissingNumbs xs =
  let shouldBeLength = length [(head xs)..(last xs)]
      pivot = round $ fromIntegral (shouldBeLength) / 2
      pivotValue = xs !! (pivot - 1)
      lower = filter (< pivotValue) xs
      upper = filter (>= pivotValue) xs
      lowerMissingCount 
        | lower == [] = 0
        | (length lower) == 1 = 0
        | otherwise = (length [(head lower)..(last lower)]) - (length lower)
      upperMissingCount 
        | upper == [] = 0
        | (length upper) == 1 = 0
        | otherwise = (length [(head upper)..(last upper)]) - (length upper)
      missingLowerValues 
        | (lowerMissingCount) == 1 = findMissingNumber (lower)
        | (lowerMissingCount) > 1 = findMissingNumbs (lower)
        | (lowerMissingCount) == 0 = []
        | otherwise = []
      missingUpperValues
        | (upperMissingCount) == 1 = findMissingNumber (upper)
        | (upperMissingCount) > 1 = findMissingNumbs (upper)
        | (upperMissingCount) == 0 = []
        | otherwise = []
  in
     missingLowerValues ++ [] ++ missingUpperValues

sum' :: (Num k) => [k] -> k
sum' xs = foldl' (+) 0 xs

main = do
  putStrLn "Enter a list size: "
  listSize <- readLn
  intToRemove <- sequence $ replicate 5 $ randomRIO (1, (listSize :: Int))
  putStrLn $ "Int to remove is: " ++ show intToRemove
  let defaultList = [1..(listSize :: Int)]
  let missingNumbers = findMissingNumbs $ (filter (not . (`elem` intToRemove)) defaultList)
  putStrLn $ "The missing number is " ++ show missingNumbers

0 个答案:

没有答案