根據N種規格中的M種規格值生成的全部規格組合的一種算法

近來在開發SKU模塊的時候,遇到這樣一個需求,某種商品有N(用未知數N來表示是因爲規格的數組由用戶制定且隨時可以編輯的,所以對程序來說,它是一個未知數)類規格,每一類規格又有M個規格值,各種規格值的組合便是一個型號,比如說,顏色是商品規格的一類,可能的值有紅、黃、綠、藍,而尺碼是另一類規格,可能的取值有LM。那它們的規格組合數爲:4*2 = 8,如果再另一類規格是版型,分別爲修身和寬鬆,那就有4 * 2 * 2 = 16種組合了。怎樣簡單高效地求出這些組合呢?

這類問題首先考慮的方法是用遞歸,但返回之間並沒有相互依賴的關係,到底什麼時候結束是個問題,用嵌套的循環又會由於數組的維度及深度不得而知而變得困難重重,後來,想到了一種很可能並非性能最優,但簡單直觀的方法,寫在這裏與大家分享一下,如果你有更好的算法,請不吝賜教,小弟感激不盡。

剛開始的時候想到要從多個數組中依次抽取一個元素出來,感覺去進行深度遍歷相當複雜,後來換了一種思路,其實每次只要把兩個數組合並起來,然後把這兩個數組合並的結果再與下個數組進行合併,最終,就能得出逐個抽取一個元素來進行組合的結果。這跟算組合總數的思路是一樣的,也就是2*4*3,先是求出2*4=8,再用8*3=24;這樣,24種組合的結果就得了,下面是JS代碼,供大家參考一下,我知道這肯定並非最佳算法,所以,再次希望有其它解決辦法的朋友賜教。

function generateTrRow(specItemList){
	var specValueList = [];
	for(var i in specItemList){
		var s = specItemList[i];
		var arrValue = s.value.split(',');
		specValueList.push(arrValue);
	}
	var arrGroup = [], tempGroup = [];
	if(specValueList.length > 0){
		var firstSpecValueList = specValueList[0];
		for(var i in firstSpecValueList){
			tempGroup.push([firstSpecValueList[i]]);
		}
		specValueList.splice(0, 1);
		arrGroup = generateGroup(specValueList, tempGroup);
	}
}
/**
 * 生成規格值組合的方法
 */
function generateGroup(arrSpecValueList, tempGroup){
	for(var i in arrSpecValueList){
		var s = arrSpecValueList[i];
		var newTempGroup = [];
		for(var j in tempGroup){
			for(var k in s){				
				var tempOne = [];
				for(var x in tempGroup[j]){
					tempOne.push(tempGroup[j][x]);
				}				
				tempOne.push(s[k]);				
				newTempGroup.push(tempOne);
			}
		}
		if(newTempGroup.length > 0){
			tempGroup = newTempGroup;
		}
	}
	return tempGroup;
}

其中generateTrRow方法是我生成表格中的行用到的,它主導把數組合並後刪除已合併的數組,下面的generateGroup方法則是執行把兩個數組合並的請求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章