我知道原來的問題是很早以前發佈的,但是我最近剛剛通過Prolog的一些問題解決了一些問題,並考慮了偶數/奇數置換問題幾天。我不想打開重複的問題,所以我在這裏發佈我的解決方案。
書中的問題問:爲even_permutation(Xs, Ys)
和
編寫程序odd_permutation(Xs, Ys)
是找到Ys
,奇數和偶數排列,分別 列表Xs
的。例如,even_permutation([1,2,3], [2,3,1])
和 odd_permutation([1,2,3], [2,1,3])
是正確的。
所以它要求排列生成器,而不僅僅是驗證者。 @hardmath提供了一個正確定義偶數或奇數排列的鏈接。本書的作者給出了兩個簡單的例子來說明。
對我來說,關鍵是找出一個偶數或奇數排列的遞歸定義。對於所有的置換,在Prolog中經典置換生成器使用了以下概念:
- N + 1個元素的每一個的置換是表示N的元素與(N + 1)插入到元件的排列的列表列表。
謂詞select
或insert
用於插入。
對於偶數和奇數排列,我認爲是類似的想法:
合理的是,一個元件中的奇數位置的插入表示相對於原始列表(該列表的前部,與所述第一位置的偶數個互換的,不需要互換,所以它甚至)。類似地,元素在偶數位置的插入表示相對於原始列表的奇數次交換。
如果我加入到這個規則,即空列表是它自己的,甚至置換,然後我可以定義下列謂詞如下生成奇數和偶數排列:
even_permutation([], []).
even_permutation([X|T], Perm) :-
even_permutation(T, Perm1),
insert_odd(X, Perm1, Perm).
even_permutation([X|T], Perm) :-
odd_permutation(T, Perm1),
insert_even(X, Perm1, Perm).
odd_permutation([X|T], Perm) :-
odd_permutation(T, Perm1),
insert_odd(X, Perm1, Perm).
odd_permutation([X|T], Perm) :-
even_permutation(T, Perm1),
insert_even(X, Perm1, Perm).
insert_odd(X, InList, [X|InList]).
insert_odd(X, [Y,Z|InList], [Y,Z|OutList]) :-
insert_odd(X, InList, OutList).
insert_even(X, [Y|InList], [Y,X|InList]).
insert_even(X, [Y,Z|InList], [Y,Z|OutList]) :-
insert_even(X, InList, OutList).
@hardmath任何想法 – 2011-04-07 13:27:07
喜,Wasswa Samuel。你的主題是指計數排列,但我認爲你誤解了偶數和奇數排列之間的區別。這些在排列的列舉方面沒有被定義(通常),而是關於將換位表示爲換位的產物所需的換位次數(交換兩個項目)。這總是可以做到的,實際上可以以多種方式完成,但是相同的置換將總是具有偶數或奇數個換位「因素」。 – hardmath 2011-04-07 16:12:22