Embora eu me lembre da operação de troca de exemplos de programação muitos anos atrás, acho que nunca precisei de uma operação de "troca". Então, onde você acha que precisa disso?
Stefan
@ Stefan neste momento, estou escrevendo uma função que recebe dois argumentos, e gostaria de garantir que o primeiro argumento seja o menor dos dois.
precisa saber é o seguinte
1
@ PythonNut, bem, você pode vincular o primeiro argumento (min a b)e o segundo (max a b). Esta é uma solução. Alguns argumentam que isso requer duas comparações quando uma basta, isso mesmo. Você pode lidar com isso com uma comparação ainda mais funcional, por exemplo, usando a ligação de desestruturação (cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...). Esta é outra maneira.
Mark Karpov
1
@ Mark verdade, mas, pelo menos para mim, parece que voa golpeando com granadas de mão. cl-destructuring-bindé uma ferramenta ridiculamente poderosa para este trabalho.
precisa saber é o seguinte
Respostas:
18
Se a memória me servir bem e você estiver disposto a usar, cl-libentão:
(cl-rotatef a b)
Observe que essa é a maneira Common Lisp de resolver o problema.
Para completar, você também deve incluir o seguinte clássico: a = a + b, b = a - b, a = a - b. Traduzido para Emacs Lisp, é claro :-D
Mark Karpov
1
É verdade, e para ser completo, vou apontar que, em asm ou C, o The XOR Trick funciona para qualquer coisa; registros, memória, ints, floats, structs, strings (comprimento igual) ... No Lisp, acho que apenas ints. Para grandes blocos de memória, é bom não precisar do buffer temporário.
Jtgd
@ jtgd: Para grandes blocos de memória, você pode fazer a troca segmento por segmento, com um pequeno buffer.
(min a b)
e o segundo(max a b)
. Esta é uma solução. Alguns argumentam que isso requer duas comparações quando uma basta, isso mesmo. Você pode lidar com isso com uma comparação ainda mais funcional, por exemplo, usando a ligação de desestruturação(cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...)
. Esta é outra maneira.cl-destructuring-bind
é uma ferramenta ridiculamente poderosa para este trabalho.Respostas:
Se a memória me servir bem e você estiver disposto a usar,
cl-lib
então:Observe que essa é a maneira Common Lisp de resolver o problema.
fonte
Este é o idioma elegante que eu uso ;-).
fonte
prog1
.cl-rotatef
macro expande.Se for números inteiros:
:)
fonte