检查字符串是否包含Ruby中另一个字符串的所有字符

Igg*_*ggy 8 ruby string

比方说我有一个字符串string= "aasmflathesorcerersnstonedksaottersapldrrysaahf".如果你没有注意到,你可以"harry potter and the sorcerers stone"在那里找到短语(减去空格).

我需要检查是否string包含字符串的所有元素.

string.include? ("sorcerer") #=> true
string.include? ("harrypotterandtheasorcerersstone") #=> false, even though it contains all the letters to spell harrypotterandthesorcerersstone
Run Code Online (Sandbox Code Playgroud)

包含不适用于混洗字符串.

如何检查字符串是否包含另一个字符串的所有元素?

tok*_*and 12

集合和数组交集不考虑重复的字符,但直方图/频率计数器确实:

require 'facets'

s1 = "aasmflathesorcerersnstonedksaottersapldrrysaahf"
s2 = "harrypotterandtheasorcerersstone"
freq1 = s1.chars.frequency
freq2 = s2.chars.frequency
freq2.all? { |char2, count2| freq1[char2] >= count2 } 
#=> true
Run Code Online (Sandbox Code Playgroud)

Array#frequency如果您不想要facet依赖,请编写自己的.

class Array
  def frequency
    Hash.new(0).tap { |counts| each { |v| counts[v] += 1 } }
  end
end
Run Code Online (Sandbox Code Playgroud)


Car*_*and 5

我认为如果要检查的字符串是"巫师",则string必须包括例如三个"r".如果是这样,你可以使用方法Array#difference,我建议将其添加到Ruby核心.

class Array
  def difference(other)
    h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
    reject { |e| h[e] > 0 && h[e] -= 1 }
  end
end 

str = "aasmflathesorcerersnstonedksaottersapldrrysaahf"

target = "sorcerer"
target.chars.difference(str.chars).empty?
  #=> true

target = "harrypotterandtheasorcerersstone"
target.chars.difference(str.chars).empty?
  #=> true
Run Code Online (Sandbox Code Playgroud)

如果目标的字符不仅必须在str,但必须是相同的顺序,我们可以写:

target = "sorcerer" 
r = Regexp.new "#{ target.chars.join "\.*" }"
  #=> /s.*o.*r.*c.*e.*r.*e.*r/ 
str =~ r
  #=> 2 (truthy)
Run Code Online (Sandbox Code Playgroud)

(或!!(str =~ r) #=> true)

target = "harrypotterandtheasorcerersstone"
r = Regexp.new "#{ target.chars.join "\.*" }"
  #=>  /h.*a.*r.*r.*y* ... o.*n.*e/
str =~ r
  #=> nil
Run Code Online (Sandbox Code Playgroud)