reduce 一個 笛卡爾積_dfs在笛卡爾積中的應用
阿新 • • 發佈:2021-01-13
技術標籤:reduce 一個 笛卡爾積
在掘金看了一篇有關笛卡爾積實際應用的例子,剛敲完程式碼,順便總結一下。(文章程式碼都沒有進行邊界處理)
例如商品規格的排列組合,我們給出以下陣列:
const productNames = ['iphone12', 'iphone12 Pro']
const colors = ['white', 'black']
const storages = ['64', '128', '256']
要得到結果為[['iphone12', 'white', '64'], ['iphone12', 'white', '128']....]的陣列(結果太長就不寫了),這很明顯是一個求n個集合笛卡爾積的問題。先貼一下dfs程式碼:
function getCartesianProduct(list) { const res = [] dfs(list, 0, [], res) return res } /** * @description: 輔助遞迴函式 * @param {array} list - 原陣列 * @param {number} idx - 初始層級 * @param {array} path - 遞迴經過的路徑,滿足條件後新增到res中 * @param {array} res 最終返回的結果 * @return void */ function dfs(list, idx, path, res) { if(path.length >= list.length) { res.push(path.slice()) return } for(let i=0; i<list[idx].length; ++i) { path.push(list[idx][i]) dfs(list, idx+1, path, res) path.pop() } }
用遞迴寫法程式碼相對簡單,但是不容易理解。
用迴圈來寫,更符合我們直觀感受。例如求M×N×O的笛卡爾積,可以先求M×N的笛卡爾積,結果再跟O相乘,這樣更直觀。下面使用JavaScript中Array.prototype.reduce()方法改寫:
function getCartesianProduct(list) { return list.reduce((total, cur) => { const res = [] for(let i=0; i<total.length; ++i) { for(let j=0; j<cur.length; ++j) { const flag = Array.isArray(total[i]) //total[i]的值為陣列就展開 if(flag){ res.push([...total[i], cur[j]]) } else{ res.push([total[i], cur[j]]) } } } return res }) }
參考連結:
前端電商 sku 的全排列演算法很難嗎?學會這個套路,徹底掌握排列組合。juejin.im