অ্যারে অন্যের সাবসেট কিনা তা পরীক্ষা করুন


145

সেই তালিকাটি অন্যটির উপসেট কিনা তা যাচাই করবেন কীভাবে কোনও ধারণা?

বিশেষত, আমি

List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };

টিএন 2 টি লিনকিউ ব্যবহার করে টি 1-এর একটি উপসেট কিনা তা কীভাবে পরীক্ষা করবেন?


তালিকাগুলি যদি সাজানো হয় (যেমন আপনার উদাহরণ হিসাবে) তবে এটি ও (এন + এম) সময়ে হওয়া উচিত be
কর্নেল

উত্তর:


255
bool isSubset = !t2.Except(t1).Any();

1
আমি এক্সটেনশন পদ্ধতিটি তৈরি করেছি geewwithblogs.net/mnf/archive/2011/05/13/…
মাইকেল ফ্রেইজিম

@ বুল ইকানা এই কোডটির কাজ করা সহজ, এক্সটেনশন পদ্ধতিটি অভ্যন্তরীণভাবে কাজের জন্য যদি কোনও আইক্যুয়ালিটি কম্পিউটার সরবরাহ না করে থাকে তবে ওভাররাইড হওয়া অবজেক্ট শ্রেণির পদ্ধতিগুলির সমান এবং গেটহ্যাশকোডকে কল করে।
মৃণাল কামবুজ

2
যদি তালিকাগুলি দৈর্ঘ্য n এবং m হয় তবে এই অ্যালগরিদমের সময় জটিলতা কী?
কর্নেল

2
এটি খুব ভাল হবে যদি এটি কনটেনসএল নামে একটি লিনাক পদ্ধতিতে সিদ্ধ করা হয়
সেবাস্তিয়ান প্যাটেন

60

যদি সেটগুলির সাথে কাজ করে তবে তালিকার পরিবর্তে হ্যাশসেট ব্যবহার করুন। তারপরে আপনি কেবল ইসসুবসটফ ব্যবহার করতে পারেন ()

HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};

bool isSubset = t2.IsSubsetOf(t1);

দুঃখিত যে এটি লিনকিউ ব্যবহার করে না। :-(

যদি আপনার তালিকাগুলি ব্যবহারের প্রয়োজন হয়, তবে @ জ্যারেডের সমাধানটি ক্যাভেটের সাথে কাজ করে যা আপনার বিদ্যমান যে কোনও পুনরাবৃত্তি উপাদানগুলি সরিয়ে ফেলতে হবে।


3
যথাযথভাবে। আপনি একটি সেট অপারেশন চান, তাদের জন্য ডিজাইন করা ক্লাস ব্যবহার করুন। ক্যামেরনের সমাধান সৃজনশীল, তবে হ্যাশসেটের মতো স্পষ্ট / অভিব্যক্তিপূর্ণ নয়।
টেকনোফিল

2
উম আমি দ্বিমত পোষণ করছি কারণ প্রশ্নটি বিশেষত "LINQ ব্যবহার করুন" বলে।
জেয়ার্ডপাড়

9
@ জারেদপার: তাহলে কি? কাউকে যে পথে যেতে চায় তার চেয়ে সঠিক পথ প্রদর্শন করা কি ভাল নয়?
জোনাথন অ্যালেন

একটি তালিকা তার ক্রম বজায় রাখে তবে একটি সেট তা করে না। অর্ডারটি গুরুত্বপূর্ণ হলে এটি ভুল ফলাফল দেয়।
UuDdLrLrSs

11

আপনি যদি ইউনিট-টেস্টিং করে থাকেন তবে আপনি কালেকশনআসর্টও ব্যবহার করতে পারেন s সসসসবসটফ পদ্ধতি:

CollectionAssert.IsSubsetOf(subset, superset);

উপরের ক্ষেত্রে এর অর্থ হবে:

CollectionAssert.IsSubsetOf(t2, t1);

7

এখানে পোস্ট করা অন্যদের চেয়ে এটি একটি উল্লেখযোগ্যভাবে আরও কার্যকর সমাধান, বিশেষত শীর্ষ সমাধান:

bool isSubset = t2.All(elem => t1.Contains(elem));

আপনি যদি টি 2 তে এমন একক উপাদান খুঁজে পেতে পারেন যা টি 1-এ নেই, তবে আপনি জানেন যে টি 2 টি 1-এর কোনও উপসেট নয়। এই পদ্ধতির সুবিধাটি হ'ল এটি অতিরিক্ত স্থান বরাদ্দ না করে, সমস্ত জায়গায় জায়গায় করা হয়। তদ্ব্যতীত, এই সমাধানটি উপসেট শর্তটি লঙ্ঘনকারী একটি একক উপাদান খুঁজে পাওয়ার সাথে সাথেই এটি ভেঙে ফেলতে সক্ষম হবে, অন্যরা অনুসন্ধান চালিয়ে যাবে। নীচে সমাধানটির সর্বোত্তম লম্বা ফর্মটি দেওয়া হয়েছে, যা উপরের শর্টহ্যান্ড সমাধানের তুলনায় আমার পরীক্ষাগুলিতে কেবল সামান্য দ্রুত।

bool isSubset = true;
foreach (var element in t2) {
    if (!t1.Contains(element)) {
        isSubset = false;
        break;
    }
}

আমি সমস্ত সমাধানগুলির কিছু প্রাথমিক কর্মক্ষমতা বিশ্লেষণ করেছি এবং ফলাফলগুলি কঠোর। এই দুটি দ্রবণগুলি .Except () এবং .Intersect () সমাধানের চেয়ে প্রায় 100x দ্রুত এবং অতিরিক্ত মেমরি ব্যবহার করা হয় না।


ঠিক সেটাই !t2.Except(t1).Any()করছে। লিনক পিছনে পিছনে কাজ করছে। কমপক্ষে একটি উপাদান আছে কিনা Any()তা জিজ্ঞাসা করছে IEnumerable। এই t2.Except(t1)দৃশ্যে কেবল প্রথম উপাদানটি নির্গত হয় t2যা এর মধ্যে নেই t1। প্রথম উপাদান যদি t2নেই t1এটা দ্রুততম শেষ, যদি সমস্ত উপাদান t2রয়েছে t1এটা দীর্ঘতম চালায়।
abto

বেঞ্চমার্ক কিছু বাছাই নিয়ে খেলার সময়, আমি খুঁজে পাওয়া যায় নি, যখন আপনি নিতে t1={1,2,3,...9999}এবং t2={9999,9998,99997...9000}, আপনি নিম্নলিখিত পরিমাপ পাবেন: !t2.Except(t1).Any(): 1ms -> t2.All(e => t1.Contains(e)): 702ms। এবং এটি আরও খারাপের পরিধি আরও খারাপ হবে।
abto

2
লিঙ্ক এইভাবে কাজ করেন না। t2.Except (t1)একটি IEnumerableনা একটি ফিরে আসছে Collection। এটি কেবলমাত্র সমস্ত সম্ভাব্য আইটেমকেই বের করে দেয় যদি আপনি এটির উপরে সম্পূর্ণরূপে পুনরাবৃত্তি করেন, উদাহরণস্বরূপ ToArray ()বা ভিতরে প্রবেশ না করে ToList ()বা ব্যবহার করে foreach। এই ধারণাটি সম্পর্কে আরও পড়ার জন্য লিনক ডিফেন্ডড এক্সিকিউশন অনুসন্ধান করুন ।
abto

1
লিন্কে কীভাবে পিছিয়ে দেওয়া কার্যকর হয় তা সম্পর্কে আমি পুরোপুরি অবগত। আপনি যা চান তা কার্যকরভাবে স্থগিত করতে পারেন, তবে আপনি যখন টি 2 টি 1-এর একটি উপসেট কিনা তা নির্ধারণ করতে চান, এটি বের করার জন্য আপনাকে পুরো তালিকাটি পুনরাবৃত্তি করতে হবে। এই সত্যটির আশেপাশে কোনও লাভ নেই।
ব্যবহারকারী 2325458

2
আপনার মন্তব্য থেকে উদাহরণটি নেওয়া যাক t2={1,2,3,4,5,6,7,8} t1={2,4,6,8} t2.Except(t1)=> প্রথম উপাদান টি 2 = 1 => 1 থেকে টি 1 এর পার্থক্য 1 ((2,4,6,8} এর তুলনায় চেক করা হয়েছে) => Except()প্রথম উপাদানটি নির্গত 1 => Any()একটি উপাদান পায় => Any()সত্যে ফলাফল => টি -2-তে উপাদানগুলির আর কোনও চেক নেই।
abto

6

@ এক্সটেনশন পদ্ধতি হিসাবে ক্যামেরনের সমাধান:

public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
    return !a.Except(b).Any();
}

ব্যবহার:

bool isSubset = t2.IsSubsetOf(t1);

(এটি একই রকম, তবে @ মাইকের ব্লগে পোস্ট করা পোস্টের মতো নয়)


0

@ ক্যামেরন এবং @ নীলের উত্তরগুলির উপর ভিত্তি করে আমি একটি এক্সটেনশন পদ্ধতি লিখেছিলাম যা এনুমিউরেবল ক্লাসের মতো একই পরিভাষা ব্যবহার করে।

/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
    return !values.Except(source).Any();
}

0

এখানে আমরা পরীক্ষা করে দেখছি যে যদি শিশু তালিকায় এমন কোনও উপাদান উপস্থিত থাকে (যেমন t2) যা পিতামাতাদের তালিকা (যেমন t1) দ্বারা অন্তর্ভুক্ত নেই I যদি এরকম কিছু না থাকে তবে তালিকাটি অন্যটির উপসেট হয়

উদাহরণ:

bool isSubset = !(t2.Any(x => !t1.Contains(x)));

-1

এটা চেষ্টা কর

static bool IsSubSet<A>(A[] set, A[] toCheck) {
  return set.Length == (toCheck.Intersect(set)).Count();
}

এখানে ধারণাটি হল যে ইন্টারসেকট কেবল উভয় অ্যারেতে থাকা মানগুলি ফিরিয়ে দেবে। এই মুহুর্তে যদি ফলাফলের সেটটির দৈর্ঘ্য মূল সেটের সমান হয়, তবে "সেট" এর সমস্ত উপাদানগুলি "চেক" তেও থাকে এবং অতএব "সেট" "টু চেক" এর উপসেট হয়

দ্রষ্টব্য: "সেট" এর নকল থাকলে আমার সমাধান কাজ করে না। আমি এটি পরিবর্তন করছি না কারণ আমি অন্য লোকের ভোট চুরি করতে চাই না।

ইঙ্গিত: আমি ক্যামেরনের উত্তরের পক্ষে ভোট দিয়েছি।


4
এটি কাজ করে যদি সেগুলি প্রকৃতপক্ষে সেট হয় তবে দ্বিতীয় "সেটে" পুনরাবৃত্তি উপাদানগুলি থাকে যেহেতু এটি সত্যিই একটি তালিকা। এটি শব্দার্থবিজ্ঞান সেট করেছে তা নিশ্চিত করতে আপনি হ্যাশসেট <ডাবল> ব্যবহার করতে চাইতে পারেন।
tvanfosson

যখন উভয় অ্যারেতে উপাদান থাকে, যা অন্য অ্যারেতে থাকে না তখন কাজ করে না।
দা_বারনি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.