2009-03-30 12 views
16

अगर मैं दो पर्वतमाला जो आपस में मिलते हैं:(रूबी) आप कैसे जांचते हैं कि किसी श्रेणी में किसी अन्य श्रेणी का उप-समूह है या नहीं?

x = 1..10 
y = 5..15 

जब मैं कहता हूँ:

puts x.include? y 

उत्पादन होता है:

false 

क्योंकि दो पर्वतमाला केवल आंशिक रूप से ओवरलैप।

लेकिन अगर मैं दो पंक्तियों के बीच आंशिक ओवरलैप होने पर "सत्य" होना चाहता हूं, तो मैं इसे कैसे लिखूं? दूसरे शब्दों में मुझे यह जानने का एक तरीका चाहिए कि एक श्रेणी में किसी अन्य श्रेणी का सबसेट होता है। मुझे लगता है कि रूबी में इसे लिखने का एक शानदार तरीका है, लेकिन केवल एक ही समाधान जो मैं सोच सकता हूं वे हैं वर्बोज़।

+2

आउटपुट i एस 'झूठा' क्योंकि निम्नलिखित गलत है: 'x.begin <= y और y <= x.end' --- _not_ क्योंकि वे केवल आंशिक रूप से ओवरलैप करते हैं। – Kevin

उत्तर

7

बड़ी पर्वतमाला के साथ इस का उपयोग करते हुए सावधान रहें, लेकिन यह यह करने के लिए एक सुंदर तरीका है:

(x.to_a & y.to_a).empty? 
+0

यह एक ओ (एन) स्मृति और समय बनाम @ मार्कसक्यू ओ (1) तरीका है। – Barry

+0

और वास्तव में उपयोग करने योग्य नहीं है जब आपके पास * समय * श्रेणियां हैं;) –

59

कारगर तरीका सीमा

(x.first <= y.last) and (y.first <= x.last) 
+0

यह सरणी में कनवर्ट करने से अधिक कुशल क्यों है? क्या सरणी में कनवर्ट करना बहुत सारे संसाधनों का उपयोग करता है? –

+1

ठीक है, यह मेरे से बेहतर तरीका है! – Angela

+1

इसे किसी सरणी में कनवर्ट करना एक सरणी बनाता है और इसे मानों के साथ भरता है, फिर दूसरी सरणी के लिए समान होता है, फिर मिलान करने वाले आइटमों के लिए दो सरणी खोजता है। x = 10000000..20000000 और y = 30000000..40000000 सेट करें और मेरे पास क्या मतलब है यह देखने के लिए दो विधियों का समय लें। – MarkusQ

1

एक सीमा या तो शुरूआत या एक दूसरे सीमा की समाप्ति के शामिल है, तो तुलना करने के लिए है, तो वे ओवरलैप।

(x === y.first) or (x === y.last) 

इस रूप में ही है:

x.include?(y.first) or x.include?(y.last) 
+1

देखें [मेरी टिप्पणी] (http://stackoverflow.com/questions/699448/ruby-how-do-you-check-whether-a-range-contains-a-subset-of-another-range#comment19657429_1337373) देखें कि यह सच क्यों नहीं है। – jasonkarns

1

लेकिन अगर मैं यह "सही" होने के लिए जब वहाँ दो सीमाओं के बीच आंशिक ओवरलैप चाहते हैं, कैसे मुझे लगता है कि लिखते थे?

आप एक सरणी के लिए पर्वतमाला कनवर्ट करते हैं, और & ऑपरेटर (संयोजन) उपयोग कर सकते हैं। यह दोनों एरे में होने वाले सभी तत्वों के साथ एक नई सरणी देता है। जिसके परिणामस्वरूप सरणी खाली नहीं है, तो इसका मतलब है कि, कुछ अतिव्यापी तत्वों देखते हैं कि:,

def overlap?(range_1, range_2) 
    !(range_1.to_a & range_2.to_a).empty? 
end 
+0

यह सबसे सहज समाधान की तरह लगता है। –

+1

@ क्रिस - यह "सबसे सहज" हो सकता है लेकिन 1) यह हास्यास्पद रूप से अक्षम है और 2) यह केवल पूर्णांक श्रेणियों पर काम करता है, इसलिए मैं इसका उपयोग करने की सलाह नहीं दूंगा। – MarkusQ

1

आप ओवरलैप के लिए जाँच कर रहे हैं तो मैं बस

(x.include? y.first) or (x.include? y.last) 

एक सीमा के रूप में करना चाहते हैं जाएगा दूसरे के सिरों में से कम से कम एक को शामिल करना होगा। स्वीकार्य conjuction जवाब की तुलना में यह मेरे लिए अधिक सहज है, हालांकि MarkusQ की सीमा तुलना के रूप में काफी कुशल नहीं है।

+1

यह केवल उस मामले को शामिल करता है जहां वे * आंशिक रूप से * ओवरलैप करते हैं। 'X = 3..6' और' y = 1..10' दिया गया, आपका कोड झूठा वापस आ जाएगा, लेकिन दो श्रेणियां वास्तव में ओवरलैप होती हैं। – jasonkarns

2

तुम भी, sets को पर्वतमाला परिवर्तित कर सकते हैं, क्योंकि आप मूल रूप से यहां चौराहे सेट कर रहे हैं। यदि आप दो से अधिक श्रेणियों से निपट रहे हैं तो आसान हो सकता है।

x = (1..10).to_set 
y = (5..15).to_set 
!(x & y).empty? #returns true (true == overlap, false == no overlap) 
+0

अच्छी तकनीक। – Anwar

-1

कुछ उपयोगी गणनीय तरीके:

# x is a 'subset' of y 
x.all?{|n| y.include? n} 
# x and y overlap 
x.any?{|n| y.include? n} 
# x and y do not overlap 
x.none?{|n| y.include? n} 
# x and y overlap one time 
x.one?{|n| y.include? n} 
1

इस विधि एक कुशल तरीके से एक से अधिक श्रेणियों के बीच ओवरलैप परीक्षण करने के लिए इस्तेमाल किया जा सकता:

def range_overlap?(ranges) 
    sorted_ranges = ranges.sort 
    sorted_ranges.each_cons(2).each do |r1, r2| 
    return true if r2.first <= r1.last 
    end 
    return false 
end 


def test(r) 
    puts r.inspect, range_overlap?(r) 
    puts '================' 
    r = r.reverse 
    puts r.inspect, range_overlap?(r) 
    puts '================' 
end 


test [[1,9], [10, 33]] 
test [[1,10], [5, 8]] 
test [[1,10], [10, 33]] 
संबंधित मुद्दे