给定这样的字符串:
var str = "thisisinsane";
辅以字典中的单词列表,例如:
var dic = [ "insane", "i", "is", "sin", "in", "this", "totally" ];
如何拆分str
成单词?
对于此字符串,有3个单词可识别。但是我们需要避免陷阱。为了在大多数情况下避免出现这些错误,我知道我们可以攻击左侧的句子,并尝试找到最长的单词。找到后,我们可以攻击字符串的其余部分,依此类推。
在下面:右下角的输入,可能的陷阱以及所需的输出。
thisisinsane
|
|
(this)isinsane
/ \
/ \
(this,i)sinsane (this,is)insane
/ / \
/ / \
(this,i,sin)ane (this,is,in)sane (this,is,insane)
/ <BEST IS>
/ <THIS ONE>
(this,is,in,sane)
最后,我们要获得:
var splited = ["this", "is", "insane"];
这是一个快速的实现,它将从左到右进行搜索,并首先匹配字典中最长的单词(jsfiddle)。但是,我不确定自己独立实施此方法是否非常聪明,因为这听起来像是一个复杂的领域,即使对这个主题一无所知,我也可以说这种算法存在缺陷。如果有的话,最好去寻找现有的库。
不用说,这是很快一起输入的。它没有以任何方式针对性能进行优化(它使用了递归,这实际上根本没有必要),并且也没有经过广泛的测试。不过,它适用于您的示例数据以及我测试过的一些变体。我希望将一些工作留给OP,以防我给出完整的代码示例,因此,如果您想使用它,可以随时进行改进。
var splitByDictionary = function (input, dictionary) {
"use strict";
// make sure we're going to look for longest-possible matches first
dictionary.sort( function (a, b) {
return b.length - a.length;
} );
var foundWords = [],
remaining = input;
var result = (function match () {
if( remaining.length === 0 ) {
return true;
}
for( var i = 0; i < dictionary.length; i++ ) {
if( remaining.substr( 0, dictionary[i].length ) === dictionary[i] ) {
foundWords.push( dictionary[i] );
remaining = remaining.substr( dictionary[i].length );
return match();
}
}
return false;
})();
return result ? foundWords : null;
};
var splitted = splitByDictionary( "thisisinsane", ["insane", "i", "is", "sin", "in", "this", "totally"] );
console.log( splitted ); // ["this", "is", "insane"]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句