js高效組合算法(遞歸)

當在使用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?

 

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