2011-07-03 35 views

Trả lời

21

Andrew và Alexey chỉ ra rằng việc sử dụng expr //. x_List :> DeleteCases[x, {}, Infinity] như tôi đã có trong câu trả lời trước của tôi cũng sẽ loại bỏ các {} trong blah[{f[{}]}], trong khi nó nên để nó ảnh hưởng làm Trưởng ban là f, không phải là một List. Các giải pháp, nhờ Leonid, là để không sử dụng ReplaceRepeated, nhưng Replace thay vì với thay thế được thực hiện ở tất cả các cấp độ từ 0 qua Infinity:

Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}] 

Lý do tại sao Replace công trình và ReplaceRepeated không thể nhìn từ ví dụ nhỏ này. Cân nhắc expr = {a, {}, {b, {}}, c[d, {}]}; trong TreeForm

enter image description here

Replace tác phẩm của mình bằng cách bắt đầu với biểu hiện trong cùng (s) đầu tiên, tức là, List[b,{}]c[d,{}], và các công trình lên đến nút đầu. Ở mỗi cấp, kiểm tra đầu đơn giản như nhìn lên nút bên phải phía trên và xem nó có khớp với List hay không. Nếu có, áp dụng các quy tắc và di chuyển lên một cấp độ, người khác không làm gì và di chuyển lên một cấp độ. Điều này dẫn đến một cái cây cuối cùng:

enter image description here

ReplaceRepeated (//.), mặt khác, hoạt động bằng cách bắt đầu với nút đầu nhất và vượt qua xuống cây Các giải pháp trước đây bắt đầu bằng cách kiểm tra nếu nút đầu tiên là. a List và nếu có, thì DeleteCases được áp dụng và nó di chuyển xuống cây, thay thế tàn nhẫn mọi {} nó có thể tìm thấy. Lưu ý rằng nó không kiểm tra xem đầu của biểu thức bên trong có khớp với List hay không, bởi vì quá trình truyền tải này được thực hiện bởi DeleteCases , không phải ReplaceRepeated. Khi //. di chuyển xuống thấp hơn tiếp theo nút, không có gì hơn để thay thế và nó thoát ra nhanh chóng. Đây là cây mà người ta được với giải pháp trước:

enter image description here

Lưu ý rằng {} bên c[d, {}] cũng đã được gỡ bỏ. Điều này chỉ là do thực tế là DeleteCases (với đặc điểm kỹ thuật cấp {0,Infinity} di chuyển xuống cây. Thật vậy, nếu đầu đầu tiên là một cái gì đó khác hơn List, nó sẽ bỏ qua nó và chuyển sang cấp độ tiếp theo, trong đó chỉ {} trong {b, {}} là một trận đấu. Để demostrate với expr2 = f[a, {}, {b, {}}, c[d, {}]], chúng tôi nhận

enter image description here

Lưu ý rằng trong các giải pháp hiện tại với Replace, chúng tôi sử dụng DeleteCases với đặc tả mức mặc định, mà chỉ là cấp độ đầu tiên. Nó không , do đó, hãy kiểm tra và xóa các danh sách trống sâu hơn ở cấp độ đầu tiên, đó chính xác là những gì chúng ta cần ở đây.

Mặc dù chúng tôi đã sử dụng nút đầu tiên để giải thích lý do tại sao nó không thành công, lý do giữ đúng cho mọi nút. Leonid giải thích các khái niệm này chi tiết hơn trong his book

+0

Điều này cũng sẽ xóa các danh sách trống bên trong các đầu khác ngoài danh sách và do đó mâu thuẫn với các thông số. –

+0

@Leonid: oops. Không đọc kỹ câu hỏi ... Tôi nghĩ bản chỉnh sửa của tôi nên sửa nó. – abcd

+3

Giải pháp mới của bạn rất tuyệt vời, rất hiệu quả. Nhanh hơn nhiều so với tôi. +1. –

Các vấn đề liên quan