如何使用列表删除函数中的重复元素?

时间:2018-02-27 11:28:20

标签: list function haskell element ghci

对于Haskell来说,我是一个新手,而且我对一些事情感到困惑。我试图删除此功能列表中的重复元素:

qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = 
     qsort smaller ++ [x] ++ qsort larger
     where 
          smaller = [a | a <- xs, a <= x] 
          larger = [b | b <- xs, b > x]

我尝试通过导入Data.List并使用nub []函数来执行此操作:

qsort :: [Int] -> [Int]
qsort [] = nub[]

但是,如果我做qsort [2,6,3,3],它仍会以[2,3,3,6]返回。

我是否使用了nub功能错误或者我还缺少其他什么?

谢谢

3 个答案:

答案 0 :(得分:1)

您的示例显示您只在空列表(private void ListCommands(object sender, RoutedEventArgs e) { Client.SendFrame(list); Thread.Sleep(100); var response = Client.ReceiveFrameString(); //ListHelp is a listbox ListHelp.Items.Add(response); //IF I PUT IT IN A COMBOBOX IT SHOWN AS DESCRIBED ComboBox.ItemsSource = response; } )上使用nub,但实际上并没有做任何事情。您必须将其应用于nub []主体的结果:

qsort

然而,这是不必要的昂贵,因为它在函数的每个分支上运行qsort :: [Int] -> [Int] qsort [] = [] qsort (x:xs) = nub $ qsort smaller ++ [x] ++ qsort larger where smaller = [a | a <- xs, a <= x] larger = [b | b <- xs, b > x] 。进一步的优化留给你。

答案 1 :(得分:1)

正如@Chad Gilbert's回答中指出的那样,您需要在最终排序列表中应用nub。不幸的是,这个函数是O(n^2),如果列表变长,效果会很差。

如果将相同的元素组合在一起并且只取第一个项目(这只是O(nlogn)操作),则可以将整体复杂度提高到O(n)(排序成本)。您可以使用mapgrouphead函数完成此操作。

根据这些建议,这是编写函数的另一种方法:

import Data.List

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (pivot:others) = map head $ group $ qsort lowers ++ [pivot] ++ qsort highers
    where lowers = filter (<pivot) others
          highers = filter (>=pivot) others

其工作原理如下:

*Main> qsort [2, 6, 3, 3]
[2,3,6]

答案 2 :(得分:0)

请参阅(唯一)[https://hackage.haskell.org/package/Unique-0.4.7.2/docs/Data-List-Unique.html]包中的unique功能。

unique [2,3,6,6,3]
[2,3,6]