我们说我有一个字符串,如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
包含不适用于混洗字符串。
如何检查字符串是否包含另一个字符串的所有元素?
答案 0 :(得分:12)
设置和数组交集不会考虑重复的字符,但是histogram / frequency counter会:
require 'facets'
s1 = "aasmflathesorcerersnstonedksaottersapldrrysaahf"
s2 = "harrypotterandtheasorcerersstone"
freq1 = s1.chars.frequency
freq2 = s2.chars.frequency
freq2.all? { |char2, count2| freq1[char2] >= count2 }
#=> true
如果您不想要与facet相关,请编写自己的Array#frequency
。
class Array
def frequency
Hash.new(0).tap { |counts| each { |v| counts[v] += 1 } }
end
end
答案 1 :(得分:5)
我认为如果要检查的字符串是"巫师",string
必须包含,例如,三个" r"' s。如果是这样,你可以使用我提出的方法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
如果目标的字符不仅必须在str
,而且必须是相同的顺序,我们可以写:
target = "sorcerer"
r = Regexp.new "#{ target.chars.join "\.*" }"
#=> /s.*o.*r.*c.*e.*r.*e.*r/
str =~ r
#=> 2 (truthy)
(或!!(str =~ r) #=> true
)
target = "harrypotterandtheasorcerersstone"
r = Regexp.new "#{ target.chars.join "\.*" }"
#=> /h.*a.*r.*r.*y* ... o.*n.*e/
str =~ r
#=> nil
答案 2 :(得分:2)
使用排序字符数组和子字符串的不同但不一定是更好的解决方案:
鉴于你的两个字符串...
subject = "aasmflathesorcerersnstonedksaottersapldrrysaahf"
search = "harrypotterandthesorcerersstone"
您可以使用.chars.sort.join
...
subject = subject.chars.sort.join # => "aaaaaaacddeeeeeffhhkllmnnoooprrrrrrssssssstttty"
然后生成一个子串列表以搜索:
search = search.chars.group_by(&:itself).values.map(&:join)
# => ["hh", "aa", "rrrrrr", "y", "p", "ooo", "tttt", "eeeee", "nn", "d", "sss", "c"]
您也可以使用this method
生成相同的子串集search = search.chars.sort.join.scan(/((.)\2*)/).map(&:first)
然后只需检查每个搜索子字符串是否出现在已排序的主题字符串中:
search.all? { |c| subject[c] }
答案 3 :(得分:1)
从string
字母组中创建一个二维数组,将字母数量与每个字母相关联。
以相同的方式从哈利波特字符串中创建一个二维数组。
遍历两者并进行比较。
我没有使用Ruby的经验,但这就是我开始用我最熟悉的语言(即Java)解决它的方法。