কিভাবে একটি অ্যারেতে অন্য অ্যারের সমস্ত উপাদান থাকে তা নির্ধারণ করবেন


178

প্রদত্ত:

a1 = [5, 1, 6, 14, 2, 8]

আমি এটি নির্ধারণ করতে চাই যে এতে এতে সমস্ত উপাদান রয়েছে:

a2 = [2, 6, 15]

এই ক্ষেত্রে ফলাফল হয় false

এই জাতীয় অ্যারে অন্তর্ভুক্তি সনাক্তকরণের জন্য কি কোনও অন্তর্নির্মিত রুবি / রেল পদ্ধতি রয়েছে?

এটি কার্যকর করার একটি উপায়:

a2.index{ |x| !a1.include?(x) }.nil?

এর চেয়ে ভাল, আরও পঠনযোগ্য, উপায় কি আছে?


গৃহীত উত্তর (অ্যারে বিয়োগ) দ্রুততম সমাধান। আমি তাদের সকলকে এখানে বেঞ্চমার্ক করেছি: gist.github.com/bbugh/cbbde8b48cbb16286044f6893e1f2e5f
ব্রেনব্যাগ

উত্তর:


308
a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]

a - b
=> [5, 1, 14, 8]

b - a
=> [15]

(b - a).empty?
=> false

60
এই পথেই। এটি সম্ভবত কিছুটা ছোট করা যেতে পারে(a2-a1).empty?
হলগার মাত্র

9
এটি কেবল সেটগুলির জন্য ব্যবহৃত অ্যারেগুলির জন্য কাজ করে, নকলগুলি সহ অ্যারেগুলির জন্য নয়
ক্রিস

3
@ ক্রিস - এর জন্য আপনি অ্যারে # ইউনিট ব্যবহার করে দেখতে পারেন। হোলার জাস্টের উদাহরণ সহ, এটি হবে(a2.uniq - a1.uniq).empty?
নিক

stackoverflow.com/questions/13553822/… আমি যা বোঝাতে চাইছি তা হল। অ্যারে # অনন্য স্পষ্টভাবে এটি ব্যর্থ হবে।
ক্রিস

81

সম্ভবত এটি পড়া সহজ:

a2.all? { |e| a1.include?(e) }

আপনি অ্যারে ছেদ ব্যবহার করতে পারেন:

(a1 & a2).size == a1.size

নোট যা sizeএখানে কেবল গতির জন্য ব্যবহৃত হয়, আপনি এটিও করতে পারেন (ধীর):

(a1 & a2) == a1

তবে আমার ধারণা প্রথমটি আরও বেশি পঠনযোগ্য। এই 3 টি সরল রুবি (রেল নয়)।


যদি a1 এবং a2 এর ওপি'র সংজ্ঞা এবং a1 "সমস্ত উপাদান" a2 ব্যবহার করে তবে আমি মনে করি এটি _ (a1 & a2) হওয়া উচিত ize আকার == a2.size _ যেহেতু a2 ছোট অ্যারে, যা সমস্ত হওয়া উচিত বৃহত্তর অ্যারেতে অন্তর্ভুক্ত উপাদানগুলি ('সত্য' পেতে) - সুতরাং দুটি অ্যারের ছেদটি ছোট-অ্যারের সমান দৈর্ঘ্য হওয়া উচিত যদি এর মধ্যে সমস্ত উপাদান বৃহত্তর উপস্থিত থাকে।
জোসেফকে ২

57

এটি করে অর্জন করা যায়

(a2 & a1) == a2

এটি উভয় অ্যারের ছেদ তৈরি করে, যে উপাদান থেকে রয়েছে a2সেগুলি ফিরিয়ে দেয় a1। ফলাফলটি যদি একইরকম হয় তবে a2আপনি নিশ্চিত হতে পারেন যে আপনি সমস্ত উপাদান অন্তর্ভুক্ত করেছেন a1

এই পদ্ধতিটি কেবল তখনই কাজ করে যদি সমস্ত উপাদান a2প্রথম স্থানে একে অপরের থেকে পৃথক থাকে। যদি দ্বিগুণ হয় তবে এই পদ্ধতির ব্যর্থতা। টেম্পোর একজন এখনও ততক্ষণে কাজ করে, তাই আমি আন্তরিকভাবে তার পদ্ধতির প্রস্তাব দিই (এটি সম্ভবত এটি আরও দ্রুত)।


2
lengthপদ্ধতিটি ব্যবহার করে আরও ভাল পারফর্ম করবে
পাবলো ফার্নান্দেজ

3
ছেদ সংস্থার আলাদা ক্রমে একই উপাদান থাকলে এটি কাজ করবে না। এই প্রশ্নের উত্তর দেওয়ার চেষ্টা করার সময় আমি এই কঠিন উপায়টি খুঁজে পেয়েছি: stackoverflow.com/questions/12062970/… পরে বুঝতে পেরেছি যে অনেক স্মার্ট লোকেরা এখানে ইতিমধ্যে এটি সম্পন্ন করেছে!
কিউবালিবার

1
পছন্দ করুন এটি পুনরুত্পাদন করার জন্য আপনার কাছে কিছু পরীক্ষার ডেটা রয়েছে? ফম আমার পরীক্ষাগুলি দেখে মনে হচ্ছিল ফলস্বরূপ অ্যারে প্রথম অ্যারে থেকে উপাদানগুলির ক্রম ধরে রেখেছে (সুতরাং আমার উত্তরটিতে আমার সাম্প্রতিকতম সম্পাদনা)। তবে, যদি সত্যিই এটি না হয় তবে আমি শিখতে চাই।
হলগার ঠিক

@ হোলজারজাস্ট আমি (a1 & a2) এর পরিবর্তে (a2 & a1) ভুল করেছিলাম, এজন্য আমি ত্রুটিটি দেখছিলাম। আপনি প্রথম অ্যারে থেকে অর্ডার ধরে রাখছেন এবং ঠিক রেখেছেন।
কিউবালিবারে

10

যদি কোনও সদৃশ উপাদান না থাকে বা আপনি সেগুলি সম্পর্কে চিন্তা করেন না, তবে আপনি সেট শ্রেণিটি ব্যবহার করতে পারেন :

a1 = Set.new [5, 1, 6, 14, 2, 8]
a2 = Set.new [2, 6, 15]
a1.subset?(a2)
=> false

দৃশ্যের পিছনে এটি ব্যবহার করে

all? { |o| set.include?(o) }

1

আপনি অ্যারে শ্রেণি বানর-প্যাচ করতে পারেন:

class Array
    def contains_all?(ary)
        ary.uniq.all? { |x| count(x) >= ary.count(x) }
    end
end

পরীক্ষা

irb(main):131:0> %w[a b c c].contains_all? %w[a b c]
=> true
irb(main):132:0> %w[a b c c].contains_all? %w[a b c c]
=> true
irb(main):133:0> %w[a b c c].contains_all? %w[a b c c c]
=> false
irb(main):134:0> %w[a b c c].contains_all? %w[a]
=> true
irb(main):135:0> %w[a b c c].contains_all? %w[x]
=> false
irb(main):136:0> %w[a b c c].contains_all? %w[]
=> true
irb(main):137:0> %w[a b c d].contains_all? %w[d c h]
=> false
irb(main):138:0> %w[a b c d].contains_all? %w[d b c]
=> true

অবশ্যই পদ্ধতিটি স্ট্যান্ডার্ড একা পদ্ধতি হিসাবে লেখা যেতে পারে, যেমন

def contains_all?(a,b)
    b.uniq.all? { |x| a.count(x) >= b.count(x) }
end

এবং আপনি এটি পছন্দ করতে পারেন

contains_all?(%w[a b c c], %w[c c c])

প্রকৃতপক্ষে, প্রোফাইলিংয়ের পরে, নিম্নলিখিত সংস্করণটি আরও দ্রুত এবং কোডটি আরও ছোট।

def contains_all?(a,b)
    b.all? { |x| a.count(x) >= b.count(x) }
end

0

আপনার অ্যারেগুলি কতটা বড় তা নির্ভর করে আপনি একটি কার্যকর অ্যালগরিদম হে (এন লগ এন) বিবেচনা করতে পারেন

def equal_a(a1, a2)
  a1sorted = a1.sort
  a2sorted = a2.sort
  return false if a1.length != a2.length
  0.upto(a1.length - 1) do 
    |i| return false if a1sorted[i] != a2sorted[i]
  end
end

বাছাই করার জন্য ও (এন লগ এন) এবং প্রতিটি জোড় পরীক্ষা করার জন্য ও (এন) ব্যয় হয় এইভাবে এই অ্যালগরিদমটি হ'ল (এন লগ এন)। অন্য অ্যালগরিদমগুলি অরসোর্টড অ্যারে ব্যবহার করে দ্রুত (asympototically) দ্রুত হতে পারে না।


আপনি এটি গণনা বাছাই করে ও (এন) এ করতে পারেন।
klochner

না তুমি পারবে না. গণনা বাছাই একটি সীমিত মহাবিশ্ব ব্যবহার করে এবং বড় সংখ্যক কীভাবে পেতে পারে তার কোনও সীমাবদ্ধতা রুবির নেই।
অাইকোস্টার

আপনি পারেন, কারণ আপনাকে আসলে আইটেমগুলি বাছাই করতে হবে না - আপনার কেবল একটি হ্যাশ ম্যাপিং আইটেমের প্রয়োজন -> উভয় অ্যারে গণনা করুন, তারপরে কীগুলির উপর পুনরাবৃত্তি করুন এবং গণনাগুলি তুলনা করুন।
ক্লোচনার

আপনি কি নিশ্চিত যে অ্যারে # সাজানো মার্জ সাজ্ট ব্যবহার করে?
নাট সিমার

0

(A1 - a2) বা (a1 & a2) ভিত্তিক সর্বাধিক উত্তরগুলি যদি উভয় অ্যারেতে সদৃশ উপাদান থাকে তবে কাজ করবে না। আমি এখানে পৌঁছানোর উপায় খুঁজতে গিয়ে পৌঁছেছি যে কোনও শব্দের সমস্ত অক্ষর (একটি অ্যারেতে বিভক্ত) অক্ষরের সেটগুলির অংশ ছিল (উদাহরণস্বরূপ স্ক্র্যাবলের জন্য)। এই উত্তরগুলির কোনওটিই কাজ করেনি, তবে এটি একটি করে:

def contains_all?(a1, a2)
  try = a1.chars.all? do |letter|
    a1.count(letter) <= a2.count(letter)
  end
  return try
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.