Hoán đổi hai biến trong Elisp


20

Giả sử tôi có

(setq a 1 b 2)

Làm thế nào tôi có thể trao đổi một cách tao nhã các giá trị của abkhông sử dụng một biến tạm thời?


Trong khi tôi nhớ hoạt động hoán đổi từ các ví dụ lập trình từ nhiều năm trước, tôi không nghĩ rằng mình đã từng cần một hoạt động "hoán đổi" như vậy. Vì vậy, nơi bạn tìm thấy bạn cần một điều như vậy?
Stefan

@Stefan lần này, tôi đang viết một hàm có hai đối số và tôi muốn đảm bảo rằng đối số đầu tiên là đối số nhỏ hơn trong hai đối số.
PythonNut

1
@PythonNut, bạn cũng có thể liên kết đối số đầu tiên (min a b)và thứ hai với (max a b). Đây là một giải pháp. Một số người sẽ cho rằng điều này đòi hỏi hai so sánh khi một người đủ, điều đó đúng. Bạn có thể xử lý nó với một so sánh theo cách thức chức năng hơn, ví dụ như sử dụng liên kết phá hủy (cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...). Đây là một cách khác.
Mark Karpov

1
@Mark đúng, nhưng, ít nhất với tôi, cảm giác như đang bay ruồi bằng lựu đạn. cl-destructuring-bindlà một công cụ vô cùng mạnh mẽ cho công việc này.
PythonNut

Câu trả lời:


18

Nếu bộ nhớ phục vụ tốt cho tôi và bạn sẵn sàng sử dụng cl-libthì:

(cl-rotatef a b)

Lưu ý rằng đây là cách Lisp thông thường để giải quyết vấn đề.


20

Đây là thành ngữ tao nhã tôi sử dụng ;-).

(setq a  (prog1 b (setq b  a)))

1
Này, gọn gàng quá. Tôi sẽ ghi nhớ nếu hiệu suất là một mối quan tâm.
PythonNut

1
Khéo léo và đơn giản.
Tên

1
Ồ, nó không phải là nguyên bản với tôi, bằng mọi cách. Nhưng nó có lẽ là sử dụng chính mà tôi làm prog1.
vẽ

1
Đó là khá nhiều những gì cl-rotatefmacro mở rộng đến.
abo-abo

6

Nếu đó là số nguyên:

(setq a (logxor a b))
(setq b (logxor a b))
(setq a (logxor a b))

:)


2
Để hoàn thiện, bạn cũng nên bao gồm các tác phẩm kinh điển sau: a = a + b, b = a - b, a = a - b. Tất nhiên được dịch sang Emacs Lisp :-D
Mark Karpov

1
Đúng, và để hoàn thiện tôi sẽ chỉ ra rằng trong asm hoặc C, XOR Trick hoạt động cho mọi thứ; thanh ghi, bộ nhớ, ints, float, structs, chuỗi (độ dài bằng nhau) ... Trong Lisp tôi nghĩ chỉ ints. Đối với các khối bộ nhớ lớn, thật tuyệt khi không cần bộ đệm tạm thời.
jtgd

@jtgd: Đối với các khối bộ nhớ lớn, bạn có thể thực hiện trao đổi theo từng phân đoạn, với một bộ đệm nhỏ.
Clément
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.