2010-12-28 17 views
5

Farz edelim ki, bir vektörü v alan ve bir şekilde dönüştürülen elemanlarla yeni bir vektör döndüren bir işlevim var. Bu, vektörü sıraladığını varsayan g işlevini çağırarak yapar. Yani f şöyle tanımlanabilir istiyorum:Unsort: bir permutasyonu hatırlama ve geri alma

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 *) 
] 

"unsort" yapmanın en iyi yolu nedir?

Ya da bir şekilde çalışmak gerçekten fantezi olsun ve bu olabilir:

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

EKLENDİ: en bir oyuncak örnekle bu beton yapalım. Bir vektörü alan ve varsa, bir sonraki en küçük öğeye her bir öğeye ekleyerek onu dönüştüren bir işlev istiyoruz. v sıralanır olup olmadığını çalışır biz gerçekten istediğiniz fonksiyonu, f Şimdi

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

: Yani, biz vektör sıralanır varsayarsak yazma, o yüzden bu varsayımı kılan bir yardımcı işlevi g yazalım kolaydır : TomD ve Yaroslav

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

cevap

2

sayesinde burada bunu yapmak için en özlü/zarif yolu muhtemelen:

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

ve Janus sayesinde burada belki de daha effic var ient yol:

: o 2 türlü yerine kuşaklar için 3.

yaptığı

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

Not, işte yukarıda üzerinde tavsiye bir şey olduğunu sanmıyorum gerçi, benim orijinal denemesi

Açıklamada belisarius'u ele almak için, g parametresi olarak geçmememin sebebi, g için bir yardımcı işlev olarak g düşünmemin nedeni. Bu, argümanının sıralı bir vektör olduğunu varsayabilirsem yazmak için daha kolay bir işlevim var gibi. Bu yüzden varsayalım ve daha sonra bu sarmalayıcı hile yapmak.

+1

Belki de bir parametre olarak ** g ** geçmek daha iyidir. –

+1

ya da biraz daha verimli, orijinalinizi '[[o [Sipariş] [v]} ile, [[[[[[[[[[[] [] []], [Sipariş] [1] Siparişi] ile değiştirin. – Janus

6

olası bir yöntem:

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

{g [c], g 1 g [a] gr [b], g [2], g [4], g verir [h], g [[Pi]]} başlangıçta Andrzej Kozlowsk bir yayından MathGroup [REDAKTE] yukarıda öğrenilen

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

olan

, i'nin

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

+1

Sipariş Verme^(2n) === Sipariş^2; Sipariş Verme^(2n + 1) === Sipariş Verme: D –

3

İşte Michael Pilat tarafından "tasnif sarıcı" desen suggested var daha önce

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

Bu ilk başlarda kafamı karıştırdı, çünkü biz g fonksiyonunun ne olduğu hakkında tam olarak aynı sayfada değiliz. Cevabım için güncellemeye bakın. Ama, bekle, sanırım burada yaptığınız şey, f'nin iki versiyonuna sahip olarak ayrı bir yardımcı fonksiyon (g dediğim) ihtiyacını ortadan kaldırmaktır. Akıllı! Sanırım buradan kurtulmuş olsanız, bu daha az kafa karıştırıcı olur. – dreeves