非遞迴實現不重複序列的全排列(三)

2021-08-21 22:51:10 字數 2755 閱讀 2394

?筆者曾利用進製轉換實現不重複序列全排列(但從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...