Lo mejor que se me ocurre es producir una matriz de sumas de cada par, y luego unir las filas, a-la merge sort. Siento que me falta algo de información simple que revelará una solución mucho más eficiente.
Mi algoritmo, en Haskell:
matrixOfSums list = [[a+b | b <- list, b >= a] | a <- list]
sortedSums = foldl merge [] matrixOfSums
--A normal merge, save that we remove duplicates
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = case compare x y of
LT -> x:(merge xs (y:ys))
EQ -> x:(merge xs (dropWhile (==x) ys))
GT -> y:(merge (x:xs) ys)
he encontrado una mejora menor, una que sea más susceptible a la codificación basada en secuencias perezoso. En lugar de fusionar las columnas en pares, combine todas a la vez. La ventaja es que comienzas a obtener elementos de la lista de inmediato.
-- wide-merge does a standard merge (ala merge-sort) across an arbitrary number of lists
-- wideNubMerge does this while eliminating duplicates
wideNubMerge :: Ord a => [[a]] -> [a]
wideNubMerge ls = wideNubMerge1 $ filter (/= []) ls
wideNubMerge1 [] = []
wideNubMerge1 ls = mini:(wideNubMerge rest)
where mini = minimum $ map head ls
rest = map (dropWhile (== mini)) ls
betterSortedSums = wideNubMerge matrixOfSums
Sin embargo, si usted sabe que va a utilizar todas las sumas, y no hay ventaja para conseguir algunos de ellos antes, ir con 'foldl merge []
', ya que es más rápido.
Creo que esto es O (n^3) ya que hay n posibles "esquinas superiores izquierdas" en cada etapa. –
se puede implementar este algoritmo en tiempo O (n^2 log n) mediante el almacenamiento de la primera entrada unpicked en cada fila en una cola de prioridad, pero asintóticamente esto no es mejor que sólo la generación de todas las cantidades y la clasificación. –
Si tiene dos listas en lugar de uno, de longitud m y n con m
dfeuer