2010-12-28 21 views
5

Giả sử tôi có hàm f lấy vectơ v và trả về một vectơ mới với các phần tử được biến đổi theo một cách nào đó. Nó thực hiện điều đó bằng cách gọi hàm g giả sử rằng vectơ được sắp xếp. Vì vậy, tôi muốn f được xác định như vậy:Unsort: ghi nhớ hoán vị và hoàn tác nó

f[v_] := Module[{s, r}, 
    s = Sort[v]; (* remember the permutation applied in order to sort v *) 
    r = g[s]; 
    Unsort[r]  (* apply the inverse of that permutation *) 
] 

Cách tốt nhất để thực hiện "Bỏ nhóm" là gì?

Hoặc chúng ta có thể có được thực sự ưa thích và có điều này bằng cách nào đó làm việc:

answer = Unsort[g[Sort[v]]]; 

thêm: Hãy làm cho bê tông này với một ví dụ đồ chơi. Giả sử chúng ta muốn hàm f lấy một vector và biến đổi nó bằng cách thêm vào từng phần tử thành phần nhỏ nhất tiếp theo, nếu có. Đó là dễ dàng để viết nếu chúng ta giả định các vector được sắp xếp, vì vậy chúng ta hãy viết một hàm helper g mà làm cho rằng giả định:

g[v_] := v + Prepend[[email protected], 0] 

Bây giờ cho các chức năng chúng tôi thực sự muốn, f, mà làm việc hay không v được sắp xếp :

f[v_] := (* remember the order; 
      sort it; 
      call g on it; 
      put it back in the original order; 
      return it 
     *) 

Trả lời

2

nhờ TomD và Yaroslav, đây có thể là/cách thanh lịch ngắn gọn nhất để làm điều đó:

f[v_] := g[[email protected]][[[email protected]@v]] 

và nhờ Janus, đây là một lẽ effic hơn cách ient:

f[v_] := With[{o = [email protected]}, g[v[[o]]][[[email protected]]]] 

Lưu ý rằng nó 2 loại thay vì 3.

Đối với hậu thế, đây là nỗ lực ban đầu của tôi, mặc dù tôi không nghĩ rằng nó có bất cứ điều gì để khuyên nó trên trên:

f[v_] := With[{o = Ordering[v]}, Sort[Transpose[{o,g[v[[o]]]}]][[All,-1]]] 

Để giải quyết belisarius trong các nhận xét, lý do tôi không chuyển g thành tham số là vì tôi đang nghĩ về g là hàm trợ giúp cho f. Nó giống như tôi có một chức năng f mà sẽ dễ dàng hơn để viết nếu tôi có thể giả định đối số của nó là một vector được sắp xếp. Vì vậy, tôi viết phiên bản giả định rằng và sau đó làm thủ thuật wrapper này.

+1

Có lẽ nó tốt hơn để vượt qua ** g ** như một tham số. –

+1

hoặc hiệu quả hơn một chút, thay đổi ban đầu thành 'Với [{o = Đặt hàng [v]}, Phần [g [v [[o]]]], Đặt hàng [o]]]'. – Janus

6

Một phương pháp có thể:

mylist = {c, 1, a, b, 2, 4, h, \[Pi]} 
    g /@ ([email protected])[[[email protected]@mylist]] 

cho

{g [c], g 1, g [a], g [b], g [2], g [4], g [h], g [[Pi]]}

Đó là,

([email protected])[[[email protected]@mylist]] == mylist 

tôi ban đầu được học những điều trên từ MathGroup, [EDITED] từ một bài đăng bởi Andrzej Kozlowsk i

http://forums.wolfram.com/mathgroup/archive/2007/Jun/msg00920.html

+1

Đặt hàng^(2n) === Đặt hàng^2; Đặt hàng^(2n + 1) === Thứ tự: D –

3

Dưới đây là một "phân loại wrapper" mẫu suggested Michael Pilat trước

Clear[g]; 
g[a_] := If[OrderedQ[a], a^2, Print["Failed"]]; 
g[{3, 2, 1}] 
g[a_] := g[[email protected]][[[email protected]@a]] /; Not[OrderedQ[a]]; 
g[{3, 2, 1}] 
+0

Điều này làm tôi bối rối lúc đầu, tôi nghĩ bởi vì chúng tôi không hoàn toàn trên cùng một trang về hàm g là gì. Xem cập nhật cho câu trả lời của tôi. Nhưng, chờ đợi, tôi đoán những gì bạn đang làm ở đây là obviating sự cần thiết cho một chức năng trợ giúp riêng biệt (những gì tôi gọi là g) bằng cách có hai phiên bản của f. Thông minh! Tôi nghĩ rằng điều này sẽ ít khó hiểu hơn nếu bạn đã loại bỏ g ở đây. – dreeves

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