?筆者曾利用進製轉換實現不重複序列全排列(但從0 迴圈到n^(n-1)-1,效率實在不高,經過仔細分析,發現乙個另人激動的規律,詳情見下表:a ?
bacba
dcba
cdba
cbda
cbad
bcad
bcabdca
bcda
bcad
bacd
bacbdac
badc
bacdabc
abdcabcdab
cadb
cabd
acbd
acbadcb
acdb
acbd
abcd
abcadbc
abdc
abcd
從上面**可以看出,對於「abcd」,假如先放好a(只有一種放法),再放b時,可以有ba,ab兩種放法;再放c時,則針對ba,ab 各有3種放法(ba前,ba中,ba後),再放d時,各有4種放法。所以第乙個元素排好後,第2個元素的位置可以用0,1 表示,第3個元素的位置可以用0,1 ,2表示,第n個元素的位置可以用0,1 ,2,3,...n-1表示,因而使用混合進製(筆者起的名字)可以實現陣列元素的全排列。
**如下:
sub pailie3(paramarray x())
dim starttime as single, endtime as single
dim i as integer, j as integer, num as long, n as integer
dim all as new collection, temp1 as long, temp2 as long
n = ubound(x) + 1 '元素個數
starttime = timer '開始計時
num = 1
for i = 1 to n
num = num * i? '遞迴計算n!
next
for i = 1 to num
set all = nothing '初始化集合all
all.add x(0)
temp1 = i
for j = 2 to n
temp2 = temp1 mod j
temp1 = temp1 \ j
if temp2 = 0 then
all.add x(j - 1) 'temp2為 0則放在最後
else
all.add x(j - 1), , before:=temp2 'temp2不為 0 則置於第temp2個元素前
end if
next
for j = 1 to n
debug.print all(j) & " "; '輸出
next
debug.print
next
endtime = timer
debug.print "共 " & num & " 種排列!用時 " & endtime - starttime & " 秒!"
end sub
private sub command1_click()
pailie3 "a", "b", "c", "d", "e", "f", "g"
end sub
由於集合屬於variant型別,運算速度慢,換成陣列進行同樣的轉換,發現確實快了很多:
sub pailie4(paramarray x())
dim starttime as single, endtime as single
dim i as integer, j as integer, k as integer, num as long, n as integer
dim all(), temp1 as long, temp2 as long
n = ubound(x) + 1 '元素個數
starttime = timer '開始計時
num = 1
for i = 1 to n
num = num * i? '遞迴計算n!
next
for i = 1 to num
redim all(1 to n) '初始化陣列all
all(1) = x(0)
temp1 = i
for j = 2 to n
temp2 = temp1 mod j
temp1 = temp1 \ j
if temp2 = 0 then
all(j) = x(j - 1) 'temp2為 0則放在最後
else
for k = j to temp2 + 1 step -1
all(k) = all(k - 1)? ' temp2之後的元素後移一位
next
all(temp2) = x(j - 1) 'temp2不為 0 則置於第temp2個元素前
end if
next
debug.print join(all, " ")? '輸出
next
endtime = timer
debug.print "共 " & num & " 種排列!用時 " & endtime - starttime & " 秒!"
end sub
private sub command1_click()
pailie4 "a", "b", "c", "d", "e", "f", "g"
end sub
如果用copymemory進行陣列的移動,速度應該更快,大家有興趣不妨一試。
非遞迴實現不重複序列的全排列(三)
筆者曾利用進製轉換實現不重複序列全排列 但從0 迴圈到n n 1 1,效率實在不高,經過仔細分析,發現乙個另人激動的規律,詳情見下表 a ba cbadcba cdba cbda cbad bca dbca bdca bcda bcad bacd bac bdac badc bacdabc ab d...
非遞迴實現不重複序列的全排列(一)
筆者曾寫過利用遞迴實現不重複序列全排列的例子 現在給出另乙個利用進製實現的 sub pailie1 paramarray x dim starttime as single,endtime as single dim n as integer,i as long,num as integer,j a...
非遞迴全排列實現
include include include include include include include includeusing namespace std const int max size 1000 尋找下乙個排列 假設 某個序列為 d1 d2 d3 dn 那麼在dn前找第乙個 比dn...