例如,如果space是分隔符并且
var str = "ab cde fgh ij klmn opq";
我想要
var result = [
["ab", "cde", "fgh", "ij", "klmn", "opq"],
["ab", "cde", "fgh", "ij", "klmn opq"],
["ab", "cde", "fgh", "ij klmn opq"],
//...
["ab", "cde", "fgh ij", "klmn opq"],
["ab", "cde", "fgh ij klmn", "opq"],
//...
["ab cde", "fgh", "ij", "klmn", "opq"],
["ab cde", "fgh", "ij", "klmn opq"],
//...
["ab cde", "fgh ij", "klmn opq"],
["ab cde", "fgh ij klmn", "opq"],
//...
["ab cde fgh ij klmn", "opq"]
];
解决此类问题的有效方法是什么?
我自己的尝试只解决了部分问题:
"ab"
,然后获取
"ab" + ["cde", "fgh", "ij", "klmn", "opq"], ["cde", "fgh", "ij", "klmn opq"]
... "ab cde"
,然后获取
"ab cde" + ["fgh", "ij", "klmn", "opq"], ["fgh", "ij", "klmn opq"]
... ......等等。但是这种方法不允许收集所有可能的序列(如上例所示)。
答案 0 :(得分:1)
您可以递归地构建序列。只需将第一个单词加入到rest中的每个序列构建中,或将其作为新单词添加。尽管使用此解决方案调用堆栈溢出存在一些问题。
但你可以看到基本的想法。
const str = 'ab cde fgh ij';
function getAllSequences(words) {
if (words.length === 1) {
return [words];
}
const [first, ...rest] = words;
const sequences = getAllSequences(rest);
return sequences.reduce((sequences, sequence) => {
const withFirstConnected = [].concat(first + ' ' + sequence[0], sequence.slice(1));
const withFirstUnshift = [].concat(first, sequence);
return sequences.concat([withFirstConnected], [withFirstUnshift]);
}, []);
}
console.log(getAllSequences(str.split(' ')));
另一个没有递归的版本,类似的方法,但添加了最后一个词而不是第一个。
function getAllSequences(words) {
return words.reduce(addWordToSequences, [[]]);
}
function addWordToSequences(sequences, word) {
return sequences.reduce((sequences, sequence) => {
if (sequence.length === 0) {
return [[word]];
}
const last = sequence[sequence.length - 1];
const front = sequence.slice(0, sequence.length - 1);
const withWordJoined = front.concat(last + ' ' + word);
return sequences.concat([withWordJoined], [sequence.concat(word)]);
}, []);
}
console.log(getAllSequences('something mdd ala ba'.split(' ')))
答案 1 :(得分:1)
您可以使用问题的抽象,并尝试仅分配所有项目的总和,并使用for循环来回归已经分布的部分。
function combine(array) {
function c(l, r) {
var i, p = 0;
if (l === 0) {
result.push(r.map(function (a) {
p += a;
return array.slice(p - a, p);
}));
return;
}
for (i = 1; i <= l; i++) {
c(l - i, r.concat(i));
}
}
var result = [];
c(array.length, []);
return result;
}
console.log(combine("ab cde fgh ij klmn opq".split(' ')));
答案 2 :(得分:0)
首先你需要得到一组单词,如下所示:
var setOfWords = str.split(" ");
然后,您需要获得所需的所有组合,如下所示:
function generateCombinations(setOfWords) {
var lastIndex = setOfWords.length - 1;
var firstIndex = setOfWords.length - 1;
while (lastIndex >= 0) {
while (firstIndex >= 0) {
var combination = [];
for (var index = firstIndex; index <= lastIndex; index++) {
combination.push(setOfWords);
}
var result = combination.join(" ");
//Do something with result, as it is a valid output
firstIndex--;
}
lastIndex--;
}
}
答案 3 :(得分:0)
如果您试图将连续字符串数组视为连续数字数组,那么您将很容易理解:
将您的连续字符串数组视为与此
等效[ab, cde, fgh, ij, klmn, opq] = [1, 2, 3, 4, 5, 6]
假设这使我们很容易解决问题。
初始序列:[1,2,3,4,5,6] - Seq - 1
现在,您需要了解这一点,只有当您将其下一个(字符串或数字)或其组合连在一起时才会形成继续。
示例:在初始序列中,5可以与6一起,因为6是5的紧邻(连续),但是4不能与6相同,类似4可以与组合56(连续组合)一起使用。我们需要做的就是确保这些组合连续且立即达到4。
首先我们要做的是从初始seq开始几乎没有连续序列,每个输出序列是一个输入到达另一个连续序列。
示例:
通过联合下一个获得的序列。
[1,2,3,4,56] - Seq - 2
[1,2,3,45,6] - Seq - 3
[1,2,34,5,6] - Seq - 4
[1,23,4,5,6] - Seq - 5
[12,3,4,5,6] - Seq - 6
同样我们需要评估seq-2到seq-6。
示例:
Seq-2将导致:
Input->
[1,2,3,4,56] - Seq - 2
Sequence obtained by concating their immediate next ones.
Output->
[1,2,3,4,56] - Seq - 7
[1,2,3,456] - Seq - 8
[1,2,34,56] - Seq - 9
[1,23,4,56] - Seq - 10
[12,3,4,56] - Seq - 11
现在,再次seq-7到seq-11是一组新的输入序列,就像序列seq2-seq6一样,需要对所有这些序列执行相同的连接。
现在,根据我的说法,有两种方法可以实现这一点: 1.递归 2.堆叠
虽然,我不打算为你编码,但我会简要介绍第二种方法。
Step:1. Initailly your stack in empty.
Step:2 With each input sequence you will obtain some output sequences.
Step:3 Push these output sequences back in the stack.
Step:4 Pop the top of the stack and store it in an temp array and push the outputs back to the stack.
Step:5 Temp array will store all the sequences.
显然,您需要提供一些条件检查以避免重复序列两次。 我希望这是有道理的。
另外,我建议你添加算法标签,我会给你更好的答案。它更像是一个算法问题,而不是一个javascript问题。