現(xiàn)在要實(shí)現(xiàn)一個,類似于排列組合的方法,給定一個數(shù)組(數(shù)組內(nèi)全部是數(shù)字),變化數(shù)組內(nèi)每個值的,形成不同的組合。就像下面這樣。
例如:[2,2,3] 排列出 223 = 12個不同組合
[
[1,1,1],[1,1,2],[1,1,3],
[1,2,1],[1,2,2],[1,2,3],
[2,1,1],[2,1,2],[2,1,3],
[2,2,1],[2,2,2],[2,2,3]
]
注:[2,2,3] 是不定的數(shù)字與數(shù)據(jù)長度,聽起來有點(diǎn)可怕(這要遍歷多少次啊),可實(shí)際需求就是這樣
補(bǔ)充: 如果是固定數(shù)組長度,@superme已經(jīng)給出答案,現(xiàn)在的問題是:未知數(shù)組長度與數(shù)字大小
,目前我能想到的方式是,使用 eval 來處理未知數(shù),加上superme的方法遍歷,這樣比遞歸稍簡單一些。請問大家還有什么好的方法嗎?
如果大家有好的辦法,或?qū)崿F(xiàn)方案,由于本人理解能力偏低,大神們請盡量上一個實(shí)現(xiàn)函數(shù),在下感激不盡。
如果你最多是3個數(shù)據(jù),就是supreme的方法就好了,如果還可能更多的數(shù)據(jù),甚至數(shù)據(jù)數(shù)不定,這個其實(shí)要用遞歸或者分治算法(用來解決遞歸算法層數(shù)過多的問題),這個就比較復(fù)雜了。
其實(shí)這個問題用位運(yùn)算是比較好算的,也可以結(jié)合分治來處理:
以[2,2,3]為例來介紹,我們從低位開始作為處理
2,表示1,2 二種狀態(tài),對應(yīng)1位二進(jìn)制,最大值2-1=1
2,表示1,2 二種狀態(tài),對應(yīng)1位二進(jìn)制,最大值2-1=1
3,表示1,2,3 3種狀態(tài),對應(yīng)2位二進(jìn)制,最大值3-1=2
這樣,需要1+1+2共4位二進(jìn)制數(shù)來表示所有組合,其中還需要濾除最高位的2個段的一些情況(2位2進(jìn)制數(shù)其實(shí)可以表示4種狀態(tài)的),后面注意是低位開始對應(yīng)
00 0 0,對應(yīng)1,1,1
00 0 1, 對應(yīng)2,1,1
00 1 0,對應(yīng)1,2,1
00 1 1,對應(yīng)2,2,1
01 0 0,對應(yīng)1,1,2
01 0 1,對應(yīng)2,1,2
01 1 0,對應(yīng)1,2,2
01 1 1,對應(yīng)2,2,2
10 0 0,對應(yīng)1,1,3
10 0 1,對應(yīng)2,1,3
10 1 0,對應(yīng)1,2,3
10 1 1,對應(yīng)2,2,3
11 0 0 位段超出不符合
11 0 1 位段超出不符合
11 1 0 位段超出不符合
11 1 1 位段超出不符合
算法思路就介紹到這里,實(shí)現(xiàn)其實(shí)不是太復(fù)雜,不過如果位數(shù)太多了(超出語言處理范圍)還是需要分治
這個問題如果真實(shí)的規(guī)模比較大,還需要考慮空間復(fù)雜度和時間復(fù)雜度問題,遞歸肯定是不行的,就是轉(zhuǎn)換遞歸為循環(huán),空間復(fù)雜度也不一定好(當(dāng)然實(shí)際情況下也不該由javascript來處理這么大復(fù)雜度的問題,但仍需考慮不是)。
這里再給出一個循環(huán)的方式
var arr = [2,2,3,2,5];
function MC(inarr,n){
var rt=[];
for(var i=0;i<inarr.length;i++){
for(var j=1;j<=n;j++){
var t=inarr[i].concat();
t.push(j);
rt.push(t)
}
}
return rt;
}
var mrt=[[]];
for(var i=0;i<arr.length;i++){
mrt=MC(mrt,arr[i]);
}
console.log(mrt);
var arr = [2, 2, 3,2];
var curr=[];
for(var i=1;i<=arr.length;i++){
curr.push(1)
}
var result=[];
result.push(curr.concat());
var len=arr.length;
fk:while(true){
var a=curr[len-1]++;
for(var i=len-1;i>=0;i--){
if(curr[i]>arr[i]){
if(i>=1){
curr[i-1]++;
curr[i]=1;
}else{
break fk;
}
}
}
var t=curr.concat();
result.push(t);
}
console.log(result);
和一樓的做法不一樣, 這個思路是,每次最后一位 +1 ,然后檢查,是不是需要定位了, 定位的條件是 初始給的數(shù)組每個位的值。
var arr = [2, 2, 3];
var p = []
for (var i = 1; i <= arr[0]; i++) {
for (var j = 1; j <= arr[1]; j++) {
for (var k = 1; k <= arr[2]; k++) {
p.push([i, j, k])
}
}
}
console.log(p);
let arr = [2,4,2,3];
var _arr = [];
for (var i = 0; i < arr.length; i++) {
var s = [];
for (var j = 1; j <= arr[i]; j++) {
s.push(j);
}
_arr.push(s);
}
var p = _arr.reduce(function (pre, cur) {
var a = [];
for (var i = 0; i < pre.length; i++) {
for (var j = 0; j < cur.length; j++) {
a.push([].concat(pre[i], cur[j]))
}
}
return a;
})
console.log(p)
應(yīng)該可以nlog(n) 時間復(fù)雜度,但是不會
let arr = [23,35,23,36,5];
var _arr = [];
for (var i = 0; i < arr.length; i++) {
var s = [];
for (var j = 1; j <= arr[i]; j++) {
s.push(j);
}
_arr.push(s);
}
var p = [];
function f(arr) {
var len = arr.length;
if (len < 2) {
return arr[0];
}
var mid = Math.ceil(len / 2),
left = arr.slice(0, mid),
right = arr.slice(mid);
return z(f(left), f(right));
}
function z(left, right) {
var a = [];
for (var i = 0; i < left.length; i++) {
for (var j = 0; j < right.length; j++) {
a.push([].concat(left[i], right[j]))
}
}
return p.concat(a);
}
console.log(p)
最后一種效率會高一點(diǎn)
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。