如何从字符串中收集所有可能的连续单词序列?

时间:2016-07-27 06:05:06

标签: javascript

例如,如果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"]
];

解决此类问题的有效方法是什么?

我自己的尝试只解决了部分问题:

  1. 删除"ab",然后获取 "ab" + ["cde", "fgh", "ij", "klmn", "opq"], ["cde", "fgh", "ij", "klmn opq"] ...
  2. 删除"ab cde",然后获取 "ab cde" + ["fgh", "ij", "klmn", "opq"], ["fgh", "ij", "klmn opq"] ...
  3. ......等等。但是这种方法不允许收集所有可能的序列(如上例所示)。

4 个答案:

答案 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问题。