當在使用sku商品選擇實現的過程中,發現獲取潛在SKU需要用到組合算法;
很多人用的01位移法則,我個人覺得不好,下面是我選擇方法
假如一個單品的參數組合是:A 、B、C、D 當成一個數組a[4] = [A ,B,C,D]
用C(4,m)表示從這4個數中選擇m個數,求其所有的情況。
首先要明確,求一組數的組合問題,元素是沒有位置要求的,即對於C(4,2)的求解{1,2}和{2,1}是一種情況。因此,爲了防止結果的多餘項,必須保證在求解過程中,原數組的元素位置是固定的!
1、選取一個元素,即求解C(4,1)時,按序號從數組中順序取出一個元素,結果爲A 、B、C、D
2、選取兩個元素,即求解C(4,2)時,先按序號從數組中順序取出一個元素,再在取出的元素後面的元素中選取一個元素。設這個序號爲i,則當i=4-2=2時爲止(i從0開始),因爲當i>3時,後面的元素不足1個。詳細如下:
第一次:i=0,第一個選取{A} 第二個在{B,C,D}中選一個,即求解C(3,1) 得到 (AB,AC,AD);
第二次:i=1,第一個選取{B} 第二個在{C,D}中選一個,即求解C(2,1) 得到 (BC,BD);
第三次:i=2,第一個選取{C} 第二個在{D}中選一個,即求解C(1,1); 得到 (CD), 序號爲2,此時結束
3、選取三個元素,即求解C(4,3)時,先按序號從數組中順序取出一個元素,再在取出的元素後面的元素中選取兩個元素。設這個序號爲i,則當i=4-3=1是時止(i從0開始),因爲當i>2時,後面的元素不足2個。
4、以此類推,即組合C(n,m)的求解過程是:固定位置後,按順序取出一個元素,再在此元素後面的元素中取m=m-1個元素,當取出的元素個數足夠了的時候,即此時m=0時,爲遞歸的出口。
詳細代碼:
function combination(arr, m) {
let r = [];
_([], arr, m);
return r;
function _(t, a, m) {
//t:臨時數組 a:目標數組 m:多少個數進行組合
if (m === 0) {
r[r.length] = t;//相當於push
return;
}
for (let i = 0; i <= a.length - m; i++) {
//從0開始 到n-m
let b = t.slice();//將t賦值給b 不能用=賦值,使用slice會形成新的數組賦值
b.push(a[i])
_(b, a.slice(i + 1), m - 1);
}
}
}
參考文獻:https://blog.csdn.net/qq_37969433/article/details/79249771?