Eu preciso juntar duas listas, classificá-los e remover duplicatas. Existe uma maneira melhor de fazer isso?

StackOverflow https://stackoverflow.com/questions/100048

  •  01-07-2019
  •  | 
  •  

Pergunta

Eu tenho duas listas não triados e preciso para produzir uma outra lista que é classificada e onde todos os elementos são únicos.

Os elementos podem ocorrer várias vezes em ambas as listas e eles são originalmente indiferenciado.

As minhas função seria algo parecido com isto:

(defun merge-lists (list-a list-b sort-fn)
    "Merges two lists of (x, y) coordinates sorting them and removing dupes"
    (let   ((prev nil))
        (remove-if
            (lambda (point)
                (let   ((ret-val (equal point prev)))
                    (setf prev point)
                    ret-val))
            (sort
                (merge 'list list-a list-b sort-fn) ;'
                 sort-fn))))

Existe uma maneira melhor de conseguir o mesmo?

Chamada de amostra:

[CL]> (merge-lists '(9 8 4 8 9 7 2) '(1 7 3 9 2 6) #'>)
  ==> (9 8 7 6 4 3 2 1)
Foi útil?

Solução

O nosso simpático bairro Lisp guru apontou a Remove-duplicatas funcionar .

Ele também forneceu o seguinte trecho:

(defun merge-lists (list-a list-b sort-fn test-fn)
    (sort (remove-duplicates (append list-a list-b) :test test-fn) sort-fn))

Outras dicas

Eu acho que eu iria primeiro ordenar as duas listas separadamente e depois juntá-las com uma função que também salta sobre duplicatas. Este deve ser um pouco mais rápido, uma vez que requer um menor travessia de ambas as listas.

P.S .: duvido que pode ser feito muito mais rápido que você, basicamente, sempre precisa de pelo menos um tipo e uma mesclagem. Talvez você pode combinar os dois em uma função, mas eu não ficaria surpreso se isso não faz diferença (grande).

Se as listas são classificadas antes de fundi-los, eles podem ser mescladas, duplicado-removido e ordenados ao mesmo tempo. Se eles são classificadas e duplicar-livre, então o merge / sort / função duplicado-remove se torna realmente trivial.

Na verdade, talvez seja melhor mudar a sua função de inserção para que ele executa uma inserção ordenada que verifica a existência de duplicatas. Então você sempre tem listas ordenadas que são livres de duplicatas e fundi-las é uma questão trivial.

Então, novamente, você pode preferir ter uma função de inserção rápida ao custo de triagem / removendo duplicatas mais tarde.

não seria o Remove-duplicatas funcionar operar melhor se o tipo foi aplicado antes do Remove-duplicatas?

Como Antti apontou, você provavelmente vai querer alavancagem REMOVE-duplicatas e SORT, embora eu provavelmente usar uma palavra-chave (ou argumento opcional) para a função de teste: (Defun Merge-listas (lista-1 lista-2 espécie-fn & key (teste # eql ')) ...) ou (Defun Merge-listas (lista-1 lista-2 espécie-fn & opcional (teste # 'EQL) ...)

Desta forma, você não terá que especificar a função de teste (utilizado por Remover duplicatas de teste para "São essas duplicatas considerados"), a menos que EQL não é bom o suficiente.

Parece que você precisa estar usando conjuntos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top