Là một người mới đến Clojure, tôi thường gặp khó khăn trong việc thể hiện những điều đơn giản nhất. Ví dụ, để thay thế các yếu tố cuối cùng trong một véc tơ, đó sẽ làCách thay thế phần tử cuối cùng trong một vector trong Clojure
v[-1]=new_value
trong python, tôi kết thúc với các biến thể sau đây trong Clojure:
(assoc v (dec (count v)) new_value)
đó là khá dài và không có thần sắc để nói ít nhất, hoặc
(conj (vec (butlast v)) new_value)
thậm chí còn tồi tệ hơn, vì nó có thời gian chạy là O(n)
.
Điều đó khiến tôi cảm thấy ngớ ngẩn, giống như một thượng cổ đang cố gắng sửa chữa đồng hồ Thụy Sĩ với một câu lạc bộ.
Cách Clojure phù hợp để thay thế phần tử cuối cùng trong vectơ là gì?
Để hỗ trợ O(n)
-claim tôi cho butlast
-version (Clojure 1.8):
(def v (vec (range 1e6)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 232.686159 msecs"
0
(def v (vec (range 1e7)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 2423.828127 msecs"
0
Vì vậy, về cơ bản cho 10 lần số lượng các yếu tố đó là chậm hơn 10 lần.
Cách đầu tiên của bạn là cách thực hiện. Rõ ràng, bạn có thể viết một hàm "thay thế cuối cùng" để làm sạch nó. Tôi nghĩ rằng cách thể hiện quá ngắn gọn của Python đã làm hỏng mong đợi của bạn. Tôi không nghĩ rằng chỉ mục từ phía sau là cần thiết thường xuyên đủ để cảnh báo cú pháp của riêng mình trong Clojure. 1 vì tôi muốn được chứng minh là sai. – Carcigenicate
Lưu ý: giải pháp # 3 không phải là O (n) nếu 'v' đã là một vectơ (tôi khuyên bạn nên luôn sử dụng một vector Clojure trong danh sách Clojure làm lựa chọn mặc định, trừ khi đo lường chứng minh khác). –
Đây là câu hỏi và câu trả lời được phân tách rõ ràng, nhưng tôi nghĩ rằng rất đáng để chỉ ra rằng nhiều thuật toán được biểu diễn bằng các biểu thức chỉ mục trong Python có một tương tự Clojure thành ngữ không yêu cầu chỉ mục. – glts