检查预定义数组中是否包含单词的任何PART

时间:2017-02-25 00:00:39

标签: ruby

为了举例,我有以下字符串:

"Federal INSURANCE Mortgage"

我想检查以下数组中是否存在此字符串中的任何单词:

BAD_WORDS = %w{LLC CORPORATION INSURANCE COMPANY GEICO}

在我们的示例中,存在保险。所以它应该返回true。这就是我所做的:

BAD_WORDS = %w{LLC CORPORATION INSURANCE COMPANY GEICO}
BAD_WORDS.detect {|word| "Federal INSURANCE Mortgage".index(word) }.present?
=> true 
BAD_WORDS.detect {|word| "Federal Mortgage".index(word) }.present?
=> false

这是在Ruby中解决这个问题最熟练的方法吗?

2 个答案:

答案 0 :(得分:2)

最好使用正则表达式,使用Regexp.union轻松组合此任务:

BAD_WORDS = %w{LLC CORPORATION INSURANCE COMPANY GEICO}
BAD_WORDS_RX = Regexp.union(*BAD_WORDS)

"Federal INSURANCE Mortgage".match(BAD_WORDS_RX)
# => #<MatchData "INSURANCE">

现在这也会进行部分单词匹配,这可能是不受欢迎的,但是示例中的单词都非常独特。

你的方法涉及迭代单词并另外迭代一系列坏词。这是N * M的复杂性,换句话说,它几何上很慢。随着你的字符串变得越来越长或坏名单越来越大,它将变得非常昂贵。

正则表达式创建后成本非常低,创建成本是名义上的。

原始版本的一个小改进是使用Set而不是数组。这些都有不断的查找时间。

答案 1 :(得分:1)

您的方式和答案(现在已删除)将循环输入,并循环显示每个输入字的单词,使运行时间为O(n 2 )。如果你有大量的输入和很多单词可能会变慢。

ruby​​数组交集方法在封面下使用散列,因此它可以在O(n)中执行相同的工作。

("Federal INSURANCE Mortgage".split & BAD_WORDS).any?

见这里:Computing set intersection in linear time?