检查字符串是否包含Ruby

时间:2016-08-29 18:28:04

标签: 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

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

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

4 个答案:

答案 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)

  1. string字母组中创建一个二维数组,将字母数量与每个字母相关联。

  2. 以相同的方式从哈利波特字符串中创建一个二维数组。

  3. 遍历两者并进行比较。

  4. 我没有使用Ruby的经验,但这就是我开始用我最熟悉的语言(即Java)解决它的方法。