In Haskell, how can you sort a list of infinite string lists?

So, if I have a (finite or infinite) list of (finite or infinite) lists of strings, is it possible to sort the list by length first, and then by lexicographic order, excluding duplicates? An example I / O will be:

Input:

[["a", "b", ...], ["a", "aa", "aaa"], ["b", "bb", "bbb", ...] ...]

Conclusion:

["a", "b", "aa", "bb", "aaa", "bbb", ...]

I know that the input list is not a valid haskell expression, but suppose there is such input. I tried using the merge algorithm, but it tends to hang on the inputs that I give them. Can someone explain and show a decent sorting function that can do this? If there is no such function, can you explain why?

If someone did not understand what I meant by the sort order, I meant that the shortest lines of the lines are sorted first, and if one or more lines have the same length, they are sorted using the <Operator.

Thank!

+3
source share
6 answers

, , , , , , .

, , . , , - . , , 0, , .., - , 2, , . , - , , , .

, , , .

, , , . , .

, .

+14
  • . , , .

  • .

  • , . , .

  • , (forall j. i < j = > head (lists !! i) <= head (lists !! j)).

, , . , . - , , - .. , :

mergeOnSortedHeads :: Ord b => (a -> b) -> [[a]] -> [a]
mergeOnSortedHeads _ [] = []
mergeOnSortedHeads f ([]:xs) = mergeOnSortedHeads f xs
mergeOnSortedHeads f ((x:xs):ys) =
  x : mergeOnSortedHeads f (bury xs ys)
  where
    bury [] ks = ks
    bury js [] = [js]
    bury js ([]:ks) = bury js ks
    bury jj@(j:js) ll@(kk@(k:ks):ls)
      | f j <= f k = jj : ll
      | otherwise = kk : bury jj ls

ghci> take 20 $ mergeOnSortedHeads id $ [[0,4,6], [2,3,9], [3,5..], [8]] ++ map repeat [12..]
[0,2,3,3,4,5,6,7,8,9,9,11,12,12,12,12,12,12,12,12]

btw: ?

+9

, .

, . , .

:

> s
[["a","b"],["a","aa","aaa"],["b","bb","bbb"]]

.

( Data.Ord.comparing ):

> sortBy (comparing length) s
[["a","b"],["a","aa","aaa"],["b","bb","bbb"]]

Ok. . concat sortBy , :

> sortBy (comparing length) . nub . concat $ s
["a","b","aa","bb","aaa","bbb"]

. .

+3

. , . , , length , . , , , , . , ? , .

+1

, :

, , , . , . , [10,9..]:

*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))
+1

, . " " , , , , . - :

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'] 

(, , , :)

I assume that you are working with regular expressions, so I think something like this can be done to work; I repeat the request for more information!

0
source

Source: https://habr.com/ru/post/1735755/


All Articles