দুটি অ্যারে একই বিষয়বস্তু রয়েছে কিনা তা পরীক্ষা করুন (কোনও ক্রমে)


90

আমি রুবেল ১.৮..6 ব্যবহার করছি রেল ১.২.৩ এর সাথে এবং এটি নির্ধারণ করতে হবে যে দুটি অ্যারে একই উপাদান রয়েছে কিনা তা নির্ধারণ না করেই একই উপাদান রয়েছে কিনা। অ্যারেগুলির একটির মধ্যে ডুপ্লিকেট না থাকার গ্যারান্টি রয়েছে (অন্যটি হতে পারে, যার ক্ষেত্রে উত্তরটি নেই)।

আমার প্রথম চিন্তা ছিল

require 'set'
a.to_set == b.to_set

তবে আমি ভাবছিলাম যে এটি করার কোনও আরও কার্যকর বা অভিজাত পদ্ধতি আছে কিনা।



Array.should চেষ্টা করুন = ~ another_array চেক stackoverflow.com/questions/2978922/...
গ্রীক পুরাণের দেবী

আপনি এর মাধ্যমে অনেক বিভ্রান্তি বাঁচাতে পারতেন: ১) অ্যারেগুলির উপাদানগুলি প্রয়োজনীয়ভাবে বাছাইযোগ্য কিনা তা উল্লেখ করে; এবং 2) "আপনি কি দুটি অ্যারে একই উপাদান রয়েছে" উদাহরণস্বরূপ ব্যাখ্যা করার জন্য একটি সাধারণ উদাহরণ সরবরাহ করুন (উদাহরণস্বরূপ, একই উপাদান রয়েছে [1,2]এবং [2,1,1]আছে?)
কেরি সোভেলল্যান্ড

রুবি ২.6 চালু করেছে differenceযা খুব দ্রুত এবং খুব পঠনযোগ্য উভয়ই একটি সমাধান দেয়। আরও তথ্য এখানে।
এসআরাক

উত্তর:


141

এটি সেট করতে রূপান্তর প্রয়োজন হয় না:

a.sort == b.sort

কোনও রূপান্তর নেই? .uniq.sortতাহলে কি ? এছাড়া uniqঅনুরূপ to_setঅভ্যন্তরীণভাবে প্লাস অতিরিক্ত.to_a.sort
ভিক্টর Moroz

এটি ছাড়াই এটি গ্রহণ করা যা আমি ব্যবহার করে শেষ করেছি তার সবচেয়ে কাছাকাছি, uniqএস ছাড়াই । আসলে আমি একটি অ্যারে তৈরি করে শেষ করেছি Range#to_a, তাই আমার কেবল অন্যটিতে ছিল sort
তাইমন

11
অ্যারেতে এমন উপাদান রয়েছে যা কেবল বাছাই করা যায় না (যেমন হ্যাশগুলির একটি অ্যারে)। সাহিল kাঙ্করের সমাধান আরও সাধারণ সমাধান হিসাবে দেখা দেয়।
ব্র্যাড

40

A এবং B দুটি অ্যারের জন্য: A এবং B তে একই বিষয়বস্তু রয়েছে যদি: (A-B).blank? and (B-A).blank?

অথবা আপনি কেবল এটি পরীক্ষা করতে পারেন: ((A-B) + (B-A)).blank?

@ Cort3z দ্বারা প্রস্তাবিত হিসাবে এই সমাধানটি পলিমারফিক অ্যারেগুলির জন্য কাজ করে

 A = [1 , "string", [1,2,3]]
 B = [[1,2,3] , "string", 1]
 (A-B).blank? and (B-A).blank? => true
 # while A.uniq.sort == B.uniq.sort will throw error `ArgumentError: comparison of Fixnum with String failed` 

:::::::::::: সম্পাদনা ::::::::::::::

মন্তব্যে যেমন পরামর্শ দেওয়া হয়েছে, উপরের সমাধানটি সদৃশদের জন্য ব্যর্থ হয়েছে A তবে যদিও প্রশ্নটির প্রয়োজন নেই যেহেতু প্রশ্নকর্তা নকলগুলিতে আগ্রহী নন (তিনি তার অ্যারেগুলি পরীক্ষা করার আগে সেট করতে রূপান্তর করছেন এবং সেই মুখোশগুলি সদৃশ এবং আপনি যদি তাকান এমনকি যাচাই করা উত্তর তিনি চেক করার আগে একটি। ইউনিক অপারেটর ব্যবহার করছেন এবং এটিও সদৃশ। তবে তারপরেও যদি সদৃশ আপনার আগ্রহী হয়, কেবল গণনার একটি চেক যোগ করা একই ঠিক করবে (প্রশ্ন অনুসারে কেবলমাত্র একটি অ্যারেতে সদৃশ থাকতে পারে)। সুতরাং চূড়ান্ত সমাধান হবে: A.size == B.size and ((A-B) + (B-A)).blank?


অ্যারেতে যদি সদৃশ থাকে তবে এটি ব্যর্থ হবে। যেমন, যদি A=[1]এবং B=[1,1]উভয় (A-B)এবং (B-A)ফাঁকা ফিরে আসবে। অ্যারে ডকুমেন্টেশন দেখুন ।
jtpereyda

@ ডাফ্রাজ্জামান সম্পূর্ণরূপে আপনার সাথে একমত আপনার প্রতিক্রিয়া অন্তর্ভুক্ত করার জন্য আমি আমার উত্তরটি সংশোধন করেছি you তবে আপনি যদি প্রশ্নটি (বা স্বীকৃত উত্তর) ঘুরে দেখেন তবে প্রশ্নকর্তা ব্যবহার করছেন: a.to_set == b.to_set এবং স্বীকৃত উত্তরটি ব্যবহার করছে a.uniq.sort == b.uniq.sortএবং উভয়ই এ-এর ক্ষেত্রে ঠিক একই ফলাফল দেয় ((A-B) + (B-A)).blank?[1] এবং বি = [1,1] সম্মত হন? যেহেতু তিনি কেবল তার আসল সমাধানটির চেয়ে উন্নতির জন্য বলছিলেন, আমার মূল সমাধানটি এখনও কাজ করে :)। রাজি?
সাহিল ধনখার

4
এই সমাধানটি বেশ দুর্দান্ত কারণ এটি একাধিক ধরণের অবজেক্টগুলিকে পরিচালনা করে। বলুন আপনার আছে A = [123, "test", [], some_object, nil]এবং B = A#because I am lazyতারপরে A.uniq.sortত্রুটি ছুঁড়ে ফেলবে (স্ট্রিং এবং অ্যারের তুলনা ব্যর্থ হয়েছে)।
অটোম্যাটিকো

এটি ও (এন) হবে তবে এটি অ্যারের আকারের উপর নির্ভরশীল? (লিনিয়ার)
ব্যবহারকারী3007294

4
অ্যারেগুলির আকার একই আকারে হয় তবে পুনরাবৃত্ত উপাদানগুলি একই হয় না তবে এটি কাজ করবে না। উদাহরণস্বরূপ A = [1, 1, 2]এবংB = [1, 2, 2]
বৌদি

23

গতির তুলনা

require 'benchmark/ips'
require 'set'

a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3, 4, 5, 6]

Benchmark.ips do |x|
  x.report('sort')   { a.sort == b.sort }  
  x.report('sort!')  { a.sort! == b.sort! }  
  x.report('to_set') { a.to_set == b.to_set }  
  x.report('minus')  { ((a - b) + (b - a)).empty? }  
end  

Warming up --------------------------------------
            sort    88.338k i/100ms
           sort!   118.207k i/100ms
          to_set    19.339k i/100ms
           minus    67.971k i/100ms
Calculating -------------------------------------
            sort      1.062M (± 0.9%) i/s -      5.389M in   5.075109s
           sort!      1.542M (± 1.2%) i/s -      7.802M in   5.061364s
          to_set    200.302k (± 2.1%) i/s -      1.006M in   5.022793s
           minus    783.106k (± 1.5%) i/s -      3.942M in   5.035311s

BTW elemetns ক্রম প্রভাবিত করে না sort'এর গতি
Morozov

আমাকে অবাক করে দিয়েছিল ... সেট ওপিকেশন ও (এন) সময়ের জটিলতার কারণে অন্য সকলের তুলনায় বাই-সেট তুলনা আমি আশা করেছি । যাতে কোনও কার্যকরভাবে সাজানো ক্ষেত্রে O (n লগন) প্রয়োজন। যদিও সেটগুলিতে কাস্টিং এবং মানগুলি সন্ধান করা সামগ্রিকভাবে ও (এন) সময়ে এটি তৈরি করে।
ওলেগ আফসানায়েভ

4
আমি প্রত্যাশা করব যে to_setবড় পরিমাণে অ্যারে দিয়ে আউটফর্মিং শুরু করতে হবে যেখানে ও (এন লগন) অ্যারেটি সেট করতে রূপান্তর করার জন্য প্রয়োজনীয় প্রচেষ্টাটির চেয়ে বেশি বিষয় শুরু করবে
Andrius Chamentauskas

4
এটি সহায়ক তবে সত্যই নিজের মধ্যে একটি উত্তর নয়? সম্ভবত বিদ্যমান সমাধানে এটি আরও ভাল যোগ করা?
এসআরাক

19

রুবি ২.6+

রুবি'র পরিচয় difference2.6 তে।

এটি এখানে একটি খুব দ্রুত, খুব পঠনযোগ্য সমাধান দেয়:

a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3, 4, 5, 6]

a.difference(b).any?
# => false
a.difference(b.reverse).any?
# => false

a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3]
a.difference(b).any?
# => true

মানদণ্ড চালানো:

a = Array.new(1000) { rand(100) }
b = Array.new(1000) { rand(100) }

Benchmark.ips do |x|
  x.report('sort')   { a.sort == b.sort }  
  x.report('sort!')  { a.sort! == b.sort! }  
  x.report('to_set') { a.to_set == b.to_set }  
  x.report('minus')  { ((a - b) + (b - a)).empty? }  
  x.report('difference') { a.difference(b).any? }
end

      sort     13.908k (± 2.6%) i/s -     69.513k in   5.001443s
     sort!     14.656k (± 3.0%) i/s -     73.736k in   5.035744s
    to_set     5.125k  (± 2.9%) i/s -     26.023k in   5.082083s
     minus     16.398k (± 2.2%) i/s -     83.181k in   5.074938s
difference     27.839k (± 5.2%) i/s -    141.048k in   5.080706s

আশা করি যে কাউকে সাহায্য করবে!


4
এই ক্ষেত্রে পার্থক্যটি ভেঙে যাচ্ছে a = [1, 2, 3] খ = [1, 2, 3, 4, 5] a.differences (খ) .আর? => মিথ্যা
ত্রুটি -404

16

যখন উপাদান aএবং bহয় Comparable,

a.sort == b.sort

@ স্টেনস্লাগের মন্তব্যের ভিত্তিতে @ মরির উত্তর সংশোধন করা হয়েছে


4
সুন্দর এবং যুক্তিসঙ্গত।
এরউইন রুইজাকার্স

4
... কখন aএবং bবাছাই করা যায়।
কেরি সোভোল্যান্ড

8

আপনি যদি আশা [:a, :b] != [:a, :a, :b] to_setকরেন তবে কাজ হবে না। পরিবর্তে আপনি ফ্রিকোয়েন্সি ব্যবহার করতে পারেন:

class Array
  def frequency
    p = Hash.new(0)
    each{ |v| p[v] += 1 }
    p
  end
end

[:a, :b].frequency == [:a, :a, :b].frequency #=> false
[:a, :b].frequency == [:b, :a].frequency #=> true

কেন a.sort == b.sortতিনি কেবল ফ্রিকোয়েন্সি সম্পর্কে চিন্তা করেন না?
fl00r

4
@ fl00r আইটেমগুলির তুলনা না হলে কী হবে? ["", :b].frequency == [:b, ""].frequency #=> true
ভিক্টর মোরোজ

4
এছাড়াও আপনি কার্যকরী কিছু করতে পারেনa.group_by{|i| i} == b.group_by{|i| i}
fl00r

7

যদি আপনি জানেন যে অ্যারেগুলি সমান দৈর্ঘ্যের হয় এবং অ্যারেতেও সদৃশ থাকে না তবে এটি খুব কার্যকর:

( array1 & array2 ) == array1

ব্যাখ্যা: এক্ষেত্রে &অপারেটর এ 2-এ পাওয়া যায় না এমন কোনও আইটেম সান এর একটি অনুলিপি প্রদান করে, যা উভয় অ্যারেতে কোনও ডুপ্লিকেট ছাড়াই একই বিষয়বস্তু রয়েছে তবে মূল a1 এর সমান।

Analyis: প্রদত্ত, যাতে অপরিবর্তিত, আমি অনুমান করছি এই তাই ধারাবাহিকভাবে একটি ডবল পুনরাবৃত্তির হিসাবে প্রয়োগ করা হয় O(n*n), বিশেষত বৃহৎ অ্যারে চেয়ে জন্য খারাপ a1.sort == a2.sortযা খারাপ-কেস সঙ্গে সম্পাদন করা উচিত O(n*logn)


4
: সর্বদা কাজ করে না a1 = [1,2,3], a2 = [2, 1, 3] a1 && a2আয় [2,1,3]আমার জন্য যা সমান নয়a1
কল্যাণ রঘু

কায়লান, আপনি কি বোঝাতে চাইছেন না যে এটি কখন কাজ করে a1==a2? array1সাম্যের ডানদিকে প্রতিস্থাপন করা থাকলে এটি কাজ করতে পারে array2তবে আমি সন্দেহ করি যে ফিরে আসা উপাদানগুলির ক্রমটি &গ্যারান্টিযুক্ত।
ক্যারি সোভেল্যান্ড

4
@ কল্যাণরাগু অ্যারেগুলির &জন্য একটি নির্দিষ্ট চৌরাস্তা অপারেটর, &&যৌক্তিক এবং এগুলি - এগুলি খুব আলাদা!
কিমবল

3

সংমিশ্রণ &এবং sizeখুব দ্রুত হতে পারে।

require 'benchmark/ips'
require 'set'

Benchmark.ips do |x|
  x.report('sort')   { a.sort == b.sort }  
  x.report('sort!')  { a.sort! == b.sort! }  
  x.report('to_set') { a.to_set == b.to_set }  
  x.report('minus')  { ((a - b) + (b - a)).empty? }
  x.report('&.size') { a.size == b.size && (a & b).size == a.size }  
end  

Calculating -------------------------------------
                sort    896.094k (±11.4%) i/s -      4.458M in   5.056163s
               sort!      1.237M (± 4.5%) i/s -      6.261M in   5.071796s
              to_set    224.564k (± 6.3%) i/s -      1.132M in   5.064753s
               minus      2.230M (± 7.0%) i/s -     11.171M in   5.038655s
              &.size      2.829M (± 5.4%) i/s -     14.125M in   5.010414s

2

একটি পদ্ধতির বিন্যাস ছাড়াই অ্যারের উপর পুনরাবৃত্তি হয়

# assume array a has no duplicates and you want to compare to b
!a.map { |n| b.include?(n) }.include?(false)

এটি ট্রুর অ্যারে প্রদান করে। যদি কোনও মিথ্যা উপস্থিত হয়, তবে বাইরেরটি include?সত্য ফিরে আসবে। সুতরাং এটি কোনও মিল কিনা তা নির্ধারণ করতে আপনাকে পুরো জিনিসটি উল্টাতে হবে।


@ ভিক্টর মোরোজ, আপনি সঠিক, এবং একটি ফ্রিকোয়েন্সি গণনা কেবল ও (এন) হবে।
রন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.