2 回答
![?](http://img1.sycdn.imooc.com/533e4c0500010c7602000200-100-100.jpg)
TA贡献1844条经验 获得超8个赞
ASet是快速测试成员资格的理想结构:
const containsChars = (chars, s) => {
const lookup = new Set(s);
return [...chars].every(e => lookup.has(e));
};
tests = ['abacus', 'back', 'cab', 'abs', 'car', 'banana'];
tests.forEach(word => console.log(word, containsChars('abc', word)));
这几乎肯定会比正则表达式更有效,正则表达式不太适合此类任务。O(checkString.length * requiredChars.length)由于嵌套indexOf调用,您现有的解决方案在二次时间内运行,checkString对于每个requiredChars. 但是构造一个集合是一次性的,使得整个算法为 O(n)。
但是,如果您的输入总是很小,则在每次调用时为 set 对象分配内存的开销将超过它的好处。如果是这种情况,请坚持使用现有的解决方案。如果您总是与相同的 进行比较requiredChars,您可以尝试构建Set一次并将其作为参数传入。
但是,如果这不是经常在循环中调用的热代码,请避免过早优化并选择您认为可读的解决方案(尽管在这种情况下它们几乎都相同)。在您通过分析确定它们是瓶颈之前,过度优化功能通常会适得其反。
![?](http://img1.sycdn.imooc.com/54586431000103bb02200220-100-100.jpg)
TA贡献1805条经验 获得超9个赞
它可以用正则表达式来完成,但不会更快——你必须对每个字符进行预测,这很丑陋:
const dedupe = str => [...new Set(str)].join('');
const test = (requiredChars, checkString) => {
const requiredPatterns = [...requiredChars].map(char => `(?=.*${char})`);
const pattern = new RegExp(`^${requiredPatterns.join('')}`);
return pattern.test(checkString);
};
tests = [ 'abacus', 'back', 'cab', 'abs', 'car', 'banana' ]
tests.forEach(word => {
console.log(word, test('abc', word))
});
这不是很好。使用您当前的策略,除了使用 Set 而不是数组 - Set.hasis O(1),而Array.indexOf和Array.includesare O(n)(如另一个答案所示)。
添加回答
举报