简体   繁体   English

JavaScript 算法问题:如何使用递归来解决这样的组合问题?

[英]JavaScript Algorithms question: how do I use recursion to solve such a combination problem?

we have a digit letter map that looks like this我们有一个看起来像这样的数字字母 map

const digitsLetters = new Map([
    ["2", ['a', 'b', 'c']],
    ["3", ['d', 'e', 'f']],
    ["4", ['g', 'h', 'i']],
    ["5", ['j', 'k', 'l']],
    ["6", ['m', 'n', 'o']],
    ["7", ['p', 'q', 'r', 's']],
    ["8", ['t', 'u', 'v']],
    ["9", ['w', 'x', 'y', 'z']],
  ]);

The question asks us to return the all possible letter combinations that the number could represent.问题要求我们返回数字可以代表的所有可能的字母组合。 For example, if we have "23" then first digit 2 maps to ['a', 'b', 'c'] and second digit maps to ['d', 'e', 'f'] and we end up getting ["ad","ae","af","bd","be","bf","cd","ce","cf"] .例如,如果我们有"23" ,那么第一个数字2映射到['a', 'b', 'c']和第二个数字映射到['d', 'e', 'f']我们最终得到["ad","ae","af","bd","be","bf","cd","ce","cf"]

I have found a way to produce such a combination between two arrays.我找到了一种在两个 arrays 之间产生这种组合的方法。

// this will output ["ad","ae","af","bd","be","bf","cd","ce","cf"]
['a', 'b', 'c'].map(char1 => ['d', 'e', 'f'].map(char2 => char1 + char2)).flat(2)

So I thought I could just recursively apply this algorithm for such digit until I hit the last one.所以我想我可以递归地将这个算法应用于这样的数字,直到我打到最后一个。 I think it is doable.我认为这是可行的。 However I had a hard time implementing the solution.但是,我很难实施该解决方案。 Can someone please help me?有人可以帮帮我吗?

You can basically just use map method to get array from you Map data based on string param and them implement Cartesian product algo.您基本上可以使用map方法从您的Map数据中获取基于字符串参数的数组,并实现笛卡尔积算法。

 const data = new Map([ ["2", ['a', 'b', 'c']], ["3", ['d', 'e', 'f']], ["4", ['g', 'h', 'i']], ["5", ['j', 'k', 'l']], ["6", ['m', 'n', 'o']], ["7", ['p', 'q', 'r', 's']], ["8", ['t', 'u', 'v']], ["9", ['w', 'x', 'y', 'z']], ]); function f(str, map) { const result = []; const arr = str.split('').map(c => map.get(c)) function r(data, n = 0, prev = []) { if (n === data.length) { return result.push(prev.slice()) } for (let i = 0; i < data[n].length; i++) { prev[n] = data[n][i] r(data, n + 1, prev.slice()) } } r(arr) return result; } console.log(f('23', data)) console.log(f('358', data))

Something like this像这样的东西

 const digitsLetters = new Map([ ["2", ['a', 'b', 'c']], ["3", ['d', 'e', 'f']], ["4", ['g', 'h', 'i']], ["5", ['j', 'k', 'l']], ["6", ['m', 'n', 'o']], ["7", ['p', 'q', 'r', 's']], ["8", ['t', 'u', 'v']], ["9", ['w', 'x', 'y', 'z']], ]); const foo = (arr, result = []) => { if (arr.length === 0) return result; const value = arr.shift(); if (result.length === 0) return foo(arr, value); const newResult = []; result.forEach((el) => { value.forEach((el2) => { newResult.push(el + el2); }); }); return foo(arr, newResult); }; const boo = (str) => foo(str.split('').map((symbol) => (digitsLetters.get(symbol)))); console.log(boo('')); console.log(boo('2')); console.log(boo('23')); console.log(boo('232'));

Let's consider the cartesian product f(E, F) with an example让我们用一个例子来考虑笛卡尔积f(E, F)

assume E is like ['12', '13']假设E就像['12', '13']

then you get candidates a and b , which I name as F = ['a', 'b']然后你得到候选人ab ,我将其命名为F = ['a', 'b']

f(E, F) = E x F would give ['12a', '13a', '12b', '13b'] f(E, F) = E x F将给出['12a', '13a', '12b', '13b']

(note that ExF is the same type of E , an array of string) (注意ExF是相同类型的E ,一个字符串数组)

now you can recurse on the digits given现在你可以递归给定的数字

g([digit, ...otherDigits], E) => {
  candidates = m.get(digit)
  EF = cartesianProduct(E, candidates)
  return g(otherDigits, EF)
}

Note that the initialization on E should not be the empty array, but an array of length 1 whose sole element is the "neutral" element (empty string for strings)请注意, E上的初始化不应是空数组,而是长度为 1 的数组,其唯一元素是“中性”元素(字符串为空字符串)

 const data = new Map([ ["2", ['a', 'b', 'c']], ["3", ['d', 'e', 'f']], ["4", ['g', 'h', 'i']], ["5", ['j', 'k', 'l']], ["6", ['m', 'n', 'o']], ["7", ['p', 'q', 'r', 's']], ["8", ['t', 'u', 'v']], ["9", ['w', 'x', 'y', 'z']], ]); const f = (E, F) => E.flatMap(e => F.map(f => e + f)) const g = ([digit, ...otherDigits], E=['']) => digit? g(otherDigits, f(E, data.get(digit))): E console.log(g('23'.split(''))) console.log(g('234'.split('')))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM