How would you calculate the intersection of characters between two strings?
For example (assuming we would have a method called String.intersection
):
"abc".intersection("ab") = 2
"hello".intersection("hallo") = 4
Ok, boys and girls, thanks for your massive feedback. Some more examples:
"aaa".intersection("a") = 1
"foo".intersection("bar") = 0
"abc".intersection("bc") = 2
"abc".intersection("ac") = 2
"abba".intersection("aa") = 2
Some m开发者_StackOverflow社区ore notes: Wikipedia defines intersection as follows:
Intersection of the sets A and B, denoted A ∩ B, is the set of all objects that are members of both A and B. The intersection of {1, 2, 3} and {2, 3, 4} is the set {2, 3}
Use String#count:
irb(main):001:0> "hello".count("hallo")
=> 4
irb(main):002:0> "abc".count("ab")
=> 2
This passes all your described test cases:
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
I'd use something like:
'abc'.split('') & 'ab'.split('') #=> ["a", "b"]
'hello'.split('') & 'yellow'.split('') #=> ["e", "l", "o"]
If you want a method to do it:
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"]
To get the number of characters in common just tack on .size:
'hello'.intersection('yellow').size #=> 3
If you want the count of all matching common characters:
'hello'.count('hello'.intersection('yellow').join) #=> 4
Traditionally we'd do it by building a hash using each character in the first string, along with a counter, then walk through the second string incrementing the counter for each common character:
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}
The number of common characters:
asdf.select{ |n,v| v > 0 }.size #=> 3
The count of the common characters:
asdf.values.inject(0){ |m,i| m += i } #=> 4
Basically summing up the minimum number of occurences of each common character:
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
Results:
"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
Using scan method to convert string into array and using &
intersection operator you can do like this...
('abd'.scan(/./) & 'abc'.scan(/./)).length
the easiest for me is the utilize the array intersection operator &
like below
class String
def intersection(other)
str = self.dup
str.chars & other.chars
end
end
usage like
"hello".intersection("hiho") // => ['h', '0']
"hello".intersection("hiho").size // => 2
精彩评论