2016-08-29 5 views
8

में किसी अन्य स्ट्रिंग के सभी वर्ण शामिल हैं या नहीं, मान लें कि मेरे पास स्ट्रिंग है, जैसे 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 

शामिल शफल स्ट्रिंग पर काम नहीं करता है।

मैं कैसे जांच सकता हूं कि किसी स्ट्रिंग में किसी अन्य स्ट्रिंग के सभी तत्व शामिल हैं या नहीं?

+1

कृपया दो बिंदुओं को स्पष्ट करने के लिए संपादित करें। 1. "जादूगर" को शामिल करने के लिए 'स्ट्रिंग' के लिए, 'स्ट्रिंग' में कम से कम तीन "आर" होना चाहिए? 2. आपका दूसरा उदाहरण 'झूठा' क्यों लौटाता है? –

+1

@CarySwoveland मुझे लगता है कि वह दिखा रहा है कि रुबी के 'शामिल' कैसे काम करते हैं, और 'झूठा' परिणाम अवांछनीय है। मुझे लगता है कि सवाल यह है कि बीमा कैसे करें कि दोनों मामले 'सत्य' वापस आते हैं। – meagar

+0

पीएस: यदि आप अपनी विधि कॉल के साथ ब्रांड्स का उपयोग करने जा रहे हैं (और अक्सर वे आवश्यक हैं), तो अपनी रिक्त स्थान से सावधान रहें: 'm (x, y) 'ठीक है लेकिन' m (x, y) ' एक वाक्यविन्यास त्रुटि है। आपका 'string.include? ("जादूगर") 'ठीक काम करता है क्योंकि केवल एक तर्क है ताकि आपके समूह-कोष्ठक अभी भी एक वैध अभिव्यक्ति बना सकें। –

उत्तर

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. दोनों के माध्यम से लूप और तुलना करें।

मुझे रूबी में कोई अनुभव नहीं है, लेकिन इस तरह मैं उस भाषा से निपटना शुरू कर दूंगा जो मुझे सबसे ज्यादा पता है, जो जावा है।

+1

हां, यह एक तरीका है, रूबी कोड के लिए मेरा जवाब देखें। +1 – tokland

+0

@tokland धन्यवाद। यकीन नहीं है कि मुझे एक डाउनवोट क्यों मिला ... – ITWorker

5

मुझे लगता है कि यदि स्ट्रिंग जांच की जानी "जादूगर" है, string शामिल करना चाहिए, उदाहरण के लिए, तीन "आर" के लिए। यदि ऐसा है तो आप विधि Array#difference का उपयोग कर सकते हैं, जिसे मैंने रूबी कोर में जोड़ा जाना प्रस्तावित किया है।

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

एक अलग-अलग वर्णित वर्ण सरणी और उप-तारों का उपयोग करके आवश्यक रूप से बेहतर समाधान नहीं:

अपने दो तार को देखते हुए ...

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] } 
संबंधित मुद्दे