1 回答
已采納

最初__
TA貢獻68條經驗 獲得超39個贊
第一次收到邀請回答。。不過今天才看到
代碼我就用php寫了,帶注釋,
這個題目一看排列組合,我能想到的就是 ?遞歸搜索了,以下僅為一種參考解法,并非最優
對這樣的數組取n個元素進行排列組合[[3.5],[4.6,23],[5.25,13]], ? 我把這個問題拆分成2步,一是對這個二維數組 (簡稱 a)任取 ?n ?個子一維數組組成一個新的二維數組 (簡稱 b), ?然后對 b 進行任取 n 個元素的操作,這時就是對?b 中每一個子一維數組中任取一個元素,組在一起即為題解。
例:
????a =?[[3.5],[4.6,23],[5.25,13]]
????n = 2
此時 b 有3個, 分別為
????b1 = [[3.5], [4.6,23]]
????b2 = [[3.5], ?[5.25, 13]]
????b3 = [[4.6, 23], [5.25, 13]]
再對每個 b 中每一個子一維數組中任取一個元素,?組在一起即為題解
對 b1
? ? ?【3.5,4.6,】,【3.5,23】,
對 b2
????【3.5,5.25】,【3.5,13】,
對 b3
????【4.6,5.25】,【4.6,13】,【23,5.25】,【23,13】
一下是參考代碼(2 步 都是用 遞歸做的) :
<?php //?此函數作用:任取?a?中?n?個子一維數組?,組成?b? function?aofn($a,?$b,?$n)?{ ????????? ????????//?遞歸終止條件,每次遞歸?n?-?1,?當?n?為?0?時說明以找到??n?個子一維數組 ????????//然后把組成的?b?作為第二步函數的參數傳進去 if($n?==?0)?{ $c?=?array(); //?var_dump($b); test($b,?$c,?count($b)); return?; } for($i?=?0;?$i?<?count($a);?$i?++)?{ ????????//?每次取得子一維數組放到?b?中 $b[]?=?$a[$i]; //array_slice($a,?$i+1)?:?取?a?中索引從?$i+1?位置的數組到最后組成一個新數組 //因為像?1,2?和?2,1這種是相等的,所有直接往后取 aofn(array_slice($a,?$i+1),?$b,?$n?-?1); //?每次搜索完記得移除?b?上面添加的那個子數組,繼續下一次搜索 array_pop($b); } } //?注意一下兩個函數的參數位置關系,?第一個函數中的?$b?變成了這里的?$a, //?這里的?$b?是一個空一維數組?;? //此函數作用:再對每個?a?中每一個子一維數組中任取一個元素,?組在一起 function?test($a,?$b,?$n)?{ ????????//?這里終止條件跟上面函數差不多,每次找一個,找到?n?個終止,繼續找下一輪 if($n?==?0)?{ ????????//?輸出找到存起來的元素 foreach($b?as?$k)?{ echo?$k.'?'; } echo?"\n"; return?; } ???????? ????????//這里就是每次去一個子數組出來,b每次存子數組中的一個元素,遞歸完就全部取完了 for($i?=?0;?$i?<?count($a[0]);?$i?++)?{ ???????? ????????//移除?a?的第一個子數組 $arr?=?array_shift($a); $b[]?=?$arr[$i]; test($a,?$b,?$n-1); //?每次搜索完記得移除?b?上面添加的那個子元素,繼續下一次搜索 array_pop($b); //?每次搜索完記得加入?a?上面移除的那個子數組(這個函數是添加到頭部), //繼續下一次搜索 array_unshift($a,?$arr); } } //代碼沒有寫判斷不合法輸入,只要輸入正常,輸出是沒問題的,以下是測試用例 //注意:因為是遞歸寫的,相對費時,所以不能測試?較大的數據量 $a?=?array([3.5],?[4.6,?23],?[5.25,?13]); $b?=?array(); $n?=?2; aofn($a,?$b,?$n);
? ??
添加回答
舉報
0/150
提交
取消