如何计算两个字符串共有的字符数?

时间:2011-05-20 14:54:31

标签: ruby

你如何计算两个字符串之间的字符交集?

例如(假设我们有一个名为String.intersection的方法):

"abc".intersection("ab") = 2
"hello".intersection("hallo") = 4

好的,男孩和女孩,感谢您的大量反馈。还有一些例子:

"aaa".intersection("a") = 1
"foo".intersection("bar") = 0
"abc".intersection("bc") = 2
"abc".intersection("ac") = 2
"abba".intersection("aa") = 2

更多说明: 维基百科将intersection定义如下:

  

A组和B组的交叉点,   用A∩B表示,是所有的集合   作为A和A的成员的对象   B. {1,2,3}和...的交集   {2,3,4}是集合{2,3}

6 个答案:

答案 0 :(得分:8)

使用String#count

irb(main):001:0> "hello".count("hallo")
=> 4
irb(main):002:0> "abc".count("ab")
=> 2

答案 1 :(得分:6)

这会传递您描述的所有测试用例:

class String
  def intersection(other)
    str = self.dup
    other.split(//).inject(0) do |sum, char|
      sum += 1 if str.sub!(char,'')
      sum
    end
  end
end

答案 2 :(得分:5)

我会使用类似的东西:

'abc'.split('') & 'ab'.split('') #=> ["a", "b"]
'hello'.split('') & 'yellow'.split('') #=> ["e", "l", "o"]

如果你想要一个方法:

class String
  def intersection(other)
    self.split('') & other.split('')
  end
end
'hello'.intersection('yellow') #=> ["e", "l", "o"]
'now is the time for all good men to come to the aid of their country'.intersection('jackdaws love my giant sphinx of quartz')
=> ["n", "o", "w", " ", "i", "s", "t", "h", "e", "m", "f", "r", "a", "l", "g", "d", "c", "u", "y"]

要获得共同的字符数,只需添加.size:

'hello'.intersection('yellow').size #=> 3

如果您想要计算所有匹配的常用字符:

'hello'.count('hello'.intersection('yellow').join) #=> 4

传统上我们是通过使用第一个字符串中的每个字符和一个计数器构建一个哈希来实现的,然后遍历第二个字符串,为每个公共字符递增计数器:

asdf = Hash[*'hello'.split('').map{ |s| [s, 0]}.flatten] #=> {"l"=>0, "o"=>0, "e"=>0, "h"=>0}
'yellow'.split('').each{ |s| asdf[s] += 1 if (asdf.key?(s)) }
asdf #=> {"l"=>2, "o"=>1, "e"=>1, "h"=>0}

常用字符数:

asdf.select{ |n,v| v > 0 }.size #=> 3

常用字符的数量:

asdf.values.inject(0){ |m,i| m += i } #=> 4

答案 3 :(得分:4)

基本上总结每个常见字符的最小出现次数:

class String
  def intersection(compared_to)
    common_chars = (self.split('') & compared_to.split(''))
    common_chars.inject(0) { |result, char|
      result + [self.count(char), compared_to.count(char)].min
    }
  end
end

结果:

"abc".intersection("ab")      #=> 2
"hello".intersection("hallo") #=> 4
"aaa".intersection("a")       #=> 1
"foo".intersection("bar")     #=> 0
"abc".intersection("bc")      #=> 2
"abc".intersection("ac")      #=> 2
"abba".intersection("aa")     #=> 2

答案 4 :(得分:1)

使用scan方法将字符串转换为数组并使用&交叉运算符,你可以这样做......

('abd'.scan(/./) & 'abc'.scan(/./)).length

答案 5 :(得分:0)

对我来说最简单的就是利用下面的数组交集运算符&

class String
  def intersection(other)
    str = self.dup
    str.chars & other.chars
  end
end

用法

"hello".intersection("hiho") // => ['h', '0']
"hello".intersection("hiho").size // => 2