我正在解决一个难题,我知道如何解决这个问题,但我想要一些指导和提示。
假设我有以下内容,给定n个字输入,以及m个没有空格的单词组合,我将有如下的一些功能。
4
this
is
my
dog
5
thisis // outputs 1
thisisacat // 0, since a or cat wasnt in the four words
thisisaduck // 0, no a or cat
thisismy // 1 this,is,my is amoung the four words
thisismydog // 1
我的想法
首先我想要做的是将第一个单词存储到数组中。之后,我检查这些单词中是否有任何单词是这5个单词的第一个单词
示例:检查this
是否在第一个单词thisis
中。它是!太棒了,现在从this
删除thisis
只是is
,现在删除对应于该等式的原始字符串并继续迭代左边(现在is,my,dog
是可用的)。如果我们可以继续这个过程,直到我们得到一个空字符串。我们返回1,否则返回0!
我的想法是否正确?我认为这将是一个很好的方法(顺便说一下,我想在javascript中实现这个)
答案 0 :(得分:2)
从长到短的单词排序可能在某些情况下有助于更快地找到解决方案,但这不是保证。如果最长的单词不,则包含最长单词的句子可能只有一个解决方案。
以此测试案例为例:
单词:工具箱,凳子,拳击手
句子:凳子
如果将“工具箱”作为该句子中的单词,则其余字符不能与其他有效单词匹配。然而,有一个解决方案,但只有在不使用“工具箱”这个词时才会使用。
当正则表达式被允许作为解决方案的一部分时,它非常简单。对于上面的示例,正则表达式将是:
^(toolbox|stool|boxer)*$
如果一个句子与该表达式匹配,那么它就是一个解决方案。如果没有,那么不是。这非常简单,并不需要算法。全部由正则表达式解释器完成。这是一个片段:
var words = ['this','is','a','string'];
var sentences = ['thisis','thisisastring','thisisaduck','thisisastringg','stringg'];
var regex = new RegExp('^(' + words.join('|') + ')*$');
sentences.forEach(sentence => {
// search returns a position. It should be 0:
console.log(sentence + ': ' + (sentence.search(regex) ? 'No' : 'Yes'));
});
但是在算法挑战中使用正则表达式感觉就像作弊:你并没有真正编写算法,而是依靠正则表达式实现为你完成这项工作。
您可以使用此算法:首先检查输入句子开头是否匹配单词,如果是,请从中删除第一个匹配项。然后对句子的剩余部分重复此操作。如果可以重复此操作直到没有剩余字符,那么您就有了解决方案。
如果剩下的字符无法与任何单词匹配......好吧,那么你无法断定那句话没有解决方法。可能是某些早期的单词选择是错误的,并且有另一种选择。因此,为了应对这种情况,您的算法可以回溯并尝试其他词语。
这个原则可以通过递归来实现。为了获得记忆效率,您可以保留原始句子,并在该句子中使用索引。
该算法以箭头函数testString
:
var words = ['this','is','a','string'];
var sentences = ['thisis','thisisastring','thisisaduck','thisisastringg','stringg'];
var testString = (words, str, i = 0) =>
i >= str.length || words.some( word =>
str.substr(i, word.length) == word && testString(words, str, i + word.length)
);
sentences.forEach(sentence => {
console.log(sentence + ': ' + (testString(words, sentence) ? 'Yes' : 'No'));
});
或者,非箭头函数语法相同:
var words = ['this','is','a','string'];
var sentences = ['thisis','thisisastring','thisisaduck','thisisastringg','stringg'];
var testString = function (words, str, i = 0) {
return i >= str.length || words.some(function (word) {
return str.substr(i, word.length) == word
&& testString(words, str, i + word.length);
});
}
sentences.forEach(function (sentence) {
console.log(sentence + ': ' + (testString(words, sentence) ? 'Yes' : 'No'));
});
...没有some()
,forEach()
或三元运营商:
var words = ['this','is','a','string'];
var sentences = ['thisis','thisisastring','thisisaduck','thisisastringg','stringg'];
function testString (words, str, i = 0) {
if (i >= str.length) return true;
for (var k = 0; k < words.length; k++) {
var word = words[k];
if (str.substr(i, word.length) == word
&& testString(words, str, i + word.length)) {
return true;
}
}
}
for (var n = 0; n < sentences.length; n++) {
var sentence = sentences[n];
if (testString(words, sentence)) {
console.log(sentence + ': Yes');
} else {
console.log(sentence + ': No');
}
}
答案 1 :(得分:1)
取4个字,把它们放到正则表达式中。 使用该正则表达式来拆分每个字符串。 取结果数组的长度(减去一个初始长度为1)。
var size = 'thisis'.split(/this|is|my|dog/).length - 1
或者,如果您的单词列表是数组
var search = new RegExp(words.join('|'))
var size = 'thisis'.split(search).length - 1
无论哪种方式,您都要按照已定义的单词列表拆分字符串。
您可以按长度对单词进行排序,以确保首先匹配较大的单词
words.sort(function (a, b) { return b.length - a.length })
答案 2 :(得分:0)
这是任何有兴趣的人的解决方案
var input = ['this','is','a','string']; // This will work for any input, but this is a test case
var orderedInput = input.sort(function(a,b){
return b.length - a.length;
});
var inputRegex = new RegExp(orderedInput.join('|'));
// our combonation of words can be any size in an array, just doin this since prompt in js is spammy
var testStrings = ['thisis','thisisastring','thisisaduck','thisisastringg','stringg'];
var foundCombos = (regex,str) => !str.split(regex).filter(str => str.length).length;
var finalResult = testStrings.reduce((all,str)=>{
all[str] = foundCombos(inputRegex,str);
if (all[str] === true){
all[str] = 1;
}
else{
all[str] = 0;
}
return all;
},{});
console.log(finalResult);