Si bien recuerdo la operación de intercambio de ejemplos de programación hace muchos años, no creo que alguna vez haya necesitado una operación de "intercambio". Entonces, ¿dónde encuentras que necesitas tal cosa?
Stefan
@Stefan esta vez, estoy escribiendo una función que toma dos argumentos, y me gustaría asegurarme de que el primer argumento sea el más pequeño de los dos.
PythonNut
1
@PythonNut, bueno, puedes vincular el primer argumento (min a b)y el segundo (max a b). Esta es una solución. Algunos argumentarán que esto requiere dos comparaciones cuando una es suficiente, eso es correcto. Puede manejarlo con una comparación de manera aún más funcional, por ejemplo, utilizando el enlace de desestructuración (cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...). Esta es otra forma.
Mark Karpov
1
@ Mark es cierto, pero, al menos para mí, eso se siente como aplastar moscas con granadas de mano. cl-destructuring-bindes una herramienta ridículamente poderosa para este trabajo.
PythonNut
Respuestas:
18
Si la memoria me sirve bien y estás dispuesto a usarla, cl-libentonces:
(cl-rotatef a b)
Tenga en cuenta que esta es una forma común de resolver el problema.
Para completar, también debe incluir el siguiente clásico: a = a + b, b = a - b, a = a - b. Traducido a Emacs Lisp, por supuesto :-D
Mark Karpov
1
Es cierto, y para completar, señalaré que en asm o C, The XOR Trick funciona para cualquier cosa; registros, memoria, ints, flotantes, estructuras, cadenas (longitud igual) ... En Lisp creo que solo ints. Para grandes bloques de memoria es bueno no necesitar el buffer temporal.
jtgd
@jtgd: para grandes bloques de memoria, puede hacer el intercambio segmento por segmento, con un pequeño búfer.
(min a b)
y el segundo(max a b)
. Esta es una solución. Algunos argumentarán que esto requiere dos comparaciones cuando una es suficiente, eso es correcto. Puede manejarlo con una comparación de manera aún más funcional, por ejemplo, utilizando el enlace de desestructuración(cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...)
. Esta es otra forma.cl-destructuring-bind
es una herramienta ridículamente poderosa para este trabajo.Respuestas:
Si la memoria me sirve bien y estás dispuesto a usarla,
cl-lib
entonces:Tenga en cuenta que esta es una forma común de resolver el problema.
fuente
Este es el idioma elegante que uso ;-).
fuente
prog1
.cl-rotatef
expande la macro.Si son enteros:
:)
fuente