Sorting 在Haskell中,如何对无限字符串列表进行排序?
因此,基本上,如果我有一个(有限或无限)字符串列表(有限或无限),是否可以先按长度排序,然后按字典顺序排序,排除重复项?示例输入/输出为: 输入: [“a”、“b”、…]、[“a”、“aa”、“aaa”]、[“b”、“bb”、“bbb”、…]、…] 输出: [“a”、“b”、“aa”、“bb”、“aaa”、“bbb”、…] 我知道输入列表不是有效的haskell表达式,但假设有这样的输入。我尝试使用合并算法,但它倾向于挂起我给它的输入。有人能解释并展示一个能做到这一点的像样的排序功能吗?如果没有这样的功能,你能解释一下原因吗 如果有人不理解我所说的排序顺序,我的意思是首先对最短长度的字符串进行排序,如果一个或多个字符串的长度相同,则使用<运算符对它们进行排序Sorting 在Haskell中,如何对无限字符串列表进行排序?,sorting,haskell,string,list,infinite,Sorting,Haskell,String,List,Infinite,因此,基本上,如果我有一个(有限或无限)字符串列表(有限或无限),是否可以先按长度排序,然后按字典顺序排序,排除重复项?示例输入/输出为: 输入: [“a”、“b”、…]、[“a”、“aa”、“aaa”]、[“b”、“bb”、“bbb”、…]、…] 输出: [“a”、“b”、“aa”、“bb”、“aaa”、“bbb”、…] 我知道输入列表不是有效的haskell表达式,但假设有这样的输入。我尝试使用合并算法,但它倾向于挂起我给它的输入。有人能解释并展示一个能做到这一点的像样的排序功能吗?如果没有
谢谢 好吧,我将忽略您对无限数据进行排序的请求 按子列表的长度排序,然后按字典顺序排序,我们可以很容易地做到这一点。哦,你想删除重复的 我们将从一个示例开始:
> s
[["a","b"],["a","aa","aaa"],["b","bb","bbb"]]
然后逐步构建程序
第一次长度排序(使用Data.Ord.comparing构建排序正文):
嗯。这看起来很合理。那么让我们先做concat,然后按长度alpha排序:
> sortBy (comparing length) . nub . concat $ s
["a","b","aa","bb","aaa","bbb"]
如果您的输入已排序。否则你将需要一个稍微不同的身体来肮脏 - 一般来说,不可能对无限列表进行排序。因为最小的项目可能在无限的位置,我们必须在输出它之前找到它
- 无限排序列表是可能的
- 通常,合并一个无限的排序列表是不可能的。原因和对它们进行排序是一样的
- 合并无限多个已排序列表,这些列表按头排序(对于所有i j.
=>i
head(list!!i)(a->b)->[[a]]->[a] 合并排序标头[]=[] mergeOnSortedHeads f([]:xs)=mergeOnSortedHeads f xs 合并排序头f((x:xs:ys)= x:mergeOnSortedHeads f(掩埋xs-ys) 哪里 bury[]ks=ks bury js[]=[js] bury js([]:ks)=bury js ks 埋葬jj(j:js)ll(kk(k:ks):ls) |f j取20$mergeOnSortedHeads id$[[0,4,6],[2,3,9],[3,5],[8]++映射重复[12..] [0,2,3,3,4,5,6,7,8,9,9,11,12,12,12,12,12,12,12,12]
顺便说一句:你需要它做什么?最终,你无法对无限列表进行排序,因为列表末尾的项目可能会一直渗透到结果的前面,因此在看到最后一个项目之前,你无法完成对无限列表的排序,但你的列表是无限的,因此你永远无法到达那里 您甚至可以尝试对无限列表进行排序的唯一方法需要对列表中的居民进行约束。如果列表项的值来自,并且列表的内容是唯一的,那么您至少可以在返回元素(列表的初始元素)方面取得一些进展。例如,如果列表具有不同的属性自然数,你可以返回你看到的第一个0,然后是第一个1,等等。但是直到你看到2,你才能在结果中取得任何进展,无论你在列表中走了多远。最终,如果你跳过了集合中的一个元素,因为它不在源代码中,你将停止生成新的输出元素,直到你有了整个input在手 您可以对字符串执行同样的操作,因为它们是有根据的,但是如果您计划返回所有可能的字符串,这甚至是不可行的 简言之,如果你需要这样做,你将以错误的方式解决你的问题。这不是一条通向任何你想要使用的解决方案的容易处理的道路
正如yairchu所指出的,合并有限数量的已排序的无限列表效果很好。这在很大程度上取决于输入数据的性质。如果在看到较长的和列表时,您可以“停止查找”某个长度的列表,那么每种长度的列表数量都是有限的,那么您可以继续按照升序排列长度,对其进行排序并连接结果。类似的操作应该可以:listsUptoLength n xss = takeWhile (\xs -> length xs <= n) $ xss listsUptoLength' n [] = [] listsUptoLength' n (xss:xsss) = case listsUptoLength n xss of [] -> [] xss' -> xss' : listsUptoLength' n xsss listsOfLength n xsss = concatMap (\xss -> (filter (\xs -> length xs == n) xss)) (listsUptoLength' n xsss) sortInfinite xsss = concatMap (\n -> sort . nub $ (listsOfLength n xsss)) [0..] f xs y = [xs ++ replicate n y | n <- [1..]] test = [ map (\x -> [x]) ['a'..'e'], f "" 'a', f "" 'b', f "b" 'a', f "a" 'b' ] ++ [f start 'c' | start <- f "" 'a']
listsUptoLength n xss=takeWhile(\xs->length xs[] xss'->xss:listsUptoLength'n xss listsOfLength n xsss=concatMap(\xss->(filter(\xs->length xs==n)xss))(listsUptoLength'n xsss) sortInfinite xsss=concatMap(\n->sort.nub$(listsOfLength n xsss))[0..]
fxsy=[xs++复制ny | n[x])['a'..'e'],f''a',f''b',f“b”'a',f“a”'b']++[f start'c'| start感谢大家的投入,并对迟来的回复表示歉意。事实证明,我只是以错误的方式处理了这个问题。我试图按照Yairchu所展示的方式处理问题,但我使用内置函数
进行合并,但由于明显的原因,length无法在无限列表上工作。总之,我解决了m我在创建列表的过程中会遇到排序问题,而不是在最终结果中。我想知道还有什么其他语言提供无限列表?这是一个奇怪但有用的概念。这里有一个算法可以让你在线排序: 它效率不高,但它非常懒惰,即使对无限列表进行排序,也会让您进行不同的排序生成。这是一个很好的噱头,但不是很有用。例如,对无限列表进行排序[10,9..]:length
正如您所见,排序改进了每一代。代码:*Main> take 10 $ sortingStream [10,9..] !! 0 [9,8,7,6,5,4,3,2,1,0] *Main> take 10 $ sortingStream [10,9..] !! 1 [8,7,6,5,4,3,2,1,0,-1] *Main> take 10 $ sortingStream [10,9..] !! 2 [7,6,5,4,3,2,1,0,-1,-2] *Main> take 10 $ sortingStream [10,9..] !! 3 [6,5,4,3,2,1,0,-1,-2,-3] *Main> take 10 $ sortingStream [10,9..] !! 4 [5,4,3,2,1,0,-1,-2,-3,-4] *Main> take 10 $ sortingStream [10,9..] !! 1000 [-991,-992,-993,-994,-995,-996,-997,-998,-999,-1000]
produce :: ([a] -> [a]) -> [a] -> [[a]] produce f xs = f xs : (produce f (f xs)) sortingStream :: (Ord a) => [a] -> [[a]] sortingStream = produce ss ss :: (Ord a) => [a] -> [a] ss [] = [] ss [x] = [x] ss [x,y] | x <= y = [x,y] | otherwise = [y,x] ss (x:y:xs) | x <= y = x: (ss (y:xs)) | otherwise = y:(ss (x:xs))
product::([a]->[a])->[a]->[a]] 生产f xs=f xs:(生产f(f xs)) 排序流::(Ord a)=>[a]->[a]] 排序流=生成ss ss::(Ord a)=>[a]->[a] ss[]=[] ss[x]=[x]
ss[x,y]| x您能保证输入列表按照您的示例进行排序吗?不要忘记通过单击答案下方的复选框,将最佳答案标记为答案。*Main> take 10 $ sortingStream [10,9..] !! 0 [9,8,7,6,5,4,3,2,1,0] *Main> take 10 $ sortingStream [10,9..] !! 1 [8,7,6,5,4,3,2,1,0,-1] *Main> take 10 $ sortingStream [10,9..] !! 2 [7,6,5,4,3,2,1,0,-1,-2] *Main> take 10 $ sortingStream [10,9..] !! 3 [6,5,4,3,2,1,0,-1,-2,-3] *Main> take 10 $ sortingStream [10,9..] !! 4 [5,4,3,2,1,0,-1,-2,-3,-4] *Main> take 10 $ sortingStream [10,9..] !! 1000 [-991,-992,-993,-994,-995,-996,-997,-998,-999,-1000]
produce :: ([a] -> [a]) -> [a] -> [[a]] produce f xs = f xs : (produce f (f xs)) sortingStream :: (Ord a) => [a] -> [[a]] sortingStream = produce ss ss :: (Ord a) => [a] -> [a] ss [] = [] ss [x] = [x] ss [x,y] | x <= y = [x,y] | otherwise = [y,x] ss (x:y:xs) | x <= y = x: (ss (y:xs)) | otherwise = y:(ss (x:xs))