2017-02-13 5 views
0

数学では、長さnのリストを並べ替えるときは、並べ替えを使ってリストに作用します。例:長さnのリストに作用する置換

(1 2) * (x, y, z) = (y, x, z) 
(1 n 2) * (v[1], v[2], ..., v[n]) = (v[n], v[1], ..., v[2]) 
perm * (v[1], v[2], ..., v[n]) = (v[perm(1)], v[perm(2)], ..., v[perm(n)]) 

ハスケルでこれを行うにはどうすればよいですか?

+0

これはpermの通常の定義ですか、そうですか? 'perm :: {1,2 ...、N} - > {1,2 ...、N}'となる。 O(N^2)アルゴリズムはかなりシンプルであるべきですが、 '(1 n 2)'の入力は回転であり、バイジェクションではありません。あなたの実際の入力は何ですか? – Zeta

+1

@Zeta 'n'が' 3'より大きければ '(1n2)'は '1 | - > n'、' n | - > 2'、 '2 | - > 1、他のすべての値を自分自身に返します。 –

+0

@DanielWagnerこれは私が "回転するもの"を意味するものです:)。私はその種の並べ替えを書く正しい言葉を思い出しません。 – Zeta

答えて

2

古いインデックスから新しいインデックスへのマップを作成するために、入力順列を使用します。

import Prelude hiding ((*)) 
import qualified Data.Map as M 

infixr 5 * -- right-associative so we can compose permutations conveniently 

(*) :: [Int] -> [a] -> [a] 
perm * xs = zipWith (\i _ -> xs !! M.findWithDefault i i ixMap) [0..] xs 
    where ixMap = M.fromList (zip perm (drop 1 perm ++ take 1 perm)) 

あなたはGHCiのプロンプトでのアクションでそれを見ることができます(それが使用するプログラミングではいつものようにかかわらず、1ベースのインデックスではなく、0をベース):

> [0,1] * "xyz" 
"yxz" 
> [0,4,1] * "abcde" 
"eacdb" 

これは(N^2 Oコストlog m)ここで、nはxsの長さであり、mはpermの長さです。 xsへのインデックス付けの場合は、(!!)からM.lookupに切り替えることで、これをO(n log(nm))に減らすことができます。

+1

permutationsを構成することができるので、あなたの順列を表現するために、ある種の '[a] - > [a]'新しい型を持つ方がいいでしょう。 '多かれ少なかれ'循環[1,2,3]を可能にするもの。サイクル[3,7] $ [1..10] '。 – Alec

+0

@Alec '[1,2,3] * [3,7] * [1..10]'の何が問題なのですか? –

+0

@Alec(本当に必要な場合は、 'cycle =(*)')、構文はうまく機能します。 –

関連する問題