2016-08-29 37 views
8

文字列がstring= "aasmflathesorcerersnstonedksaottersapldrrysaahf"のようになっています。あなたが気づいていない場合は、フレーズ"harry potter and the sorcerers stone"がそこにあります(スペースを差し引いたもの)。文字列にRubyの別の文字列のすべての文字が含まれているかどうか確認してください

stringに文字列のすべての要素が含まれているかどうかを確認する必要があります。

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

組み込みは、シャッフルされた文字列では機能しません。

文字列に別の文字列のすべての要素が含まれているかどうかを確認するにはどうすればよいですか?

+1

2点を明確にするために編集してください。 1. 'string 'に" sorcerer "を含めるには、少なくとも3つの" r "を' string'に含める必要がありますか? 2. 2番目の例が 'false'を返すのはなぜですか? –

+1

@CarySwovel私は彼がRubyの 'include? 'のしくみを示していると思うし、' false'結果は望ましくない。私は、両方のケースが「真」を返すようにする方法が問題だと思います。 – meagar

+0

PS:あなたのメソッド呼び出しでカッコを使うことになっているなら、あなたのスペースにも注意してください: 'm(x、y)'は問題ありませんが 'm(x、y)'構文エラーです。あなたの 'string.include? ( "sorcerer") 'はうまくいきます。なぜなら、引数が1つしかないので、あなたのグループ化の括弧が有効な式を形成しているからです。 –

答えて

11

セットと配列の交差点を繰り返し文字を考慮していませんが、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 

は、あなた自身のArray#frequencyあなたは、ファセットにしたくない場合は、依存関係を記述します。

class Array 
    def frequency 
    Hash.new(0).tap { |counts| each { |v| counts[v] += 1 } } 
    end 
end 
-1
  1. 各文字に文字の数を関連付けるために、あなたのstring手紙バンクのうちの2次元配列を作成します。

  2. 同じように2次元配列をハリーポッターストリングから作成します。

  3. ループと比較を繰り返す。

私はRubyでの経験はありませんが、これは私が最もよく知っている言語、つまりJavaで対処する方法です。

+1

はい、それは方法です、私の答えはRubyのコードを見てください。 +1 – tokland

+0

@toklandありがとう。なぜ私はdownvoteを持っているのか分かりません... – ITWorker

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 

対象の文字が唯一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

Aソートされた文字配列とサブストリングを使用すると必ずしも良い解決法ではありません。

を考えると、あなたの二つの文字列...

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] } 
関連する問題