كيفية العثور على العناصر في Superset ليست في مجموعة فرعية

StackOverflow https://stackoverflow.com/questions/1911646

  •  19-09-2019
  •  | 
  •  

سؤال

وأنا أعلم أن هناك "لا" على ienumerable بفضل Linq الذي يأخذ مجموعة لا يعارضها، لكنني قلق بشأن الأداء الكبير أوه ما هو أسرع خوارزمية للقيام بذلك؟

هل كانت مفيدة؟

المحلول

الطريقة الوحيدة لإزالة مجموعة فرعية من العناصر من IEnumerable<T> هو حلقة من خلال Superset ولكل عنصر في حلقة SuperSet من خلال المجموعة الفرعية، وإزالة هذا البند من SuperSet إذا تم العثور عليه في المجموعة الفرعية.

هذا سوف أعطيك O (N²) في المتوسط.

الآن إذا كانت هناك معلومات إضافية حول هذه المجموعات (ربما واحدة أو كلاهما هي قائمة أو ربما يتم فرزها واحدة أو كليهما أو كليهما) التي يمكن أن تساعدك في إنشاء حل أكثر أداء.

إذا كنت مهتما، فإليك طريقة تمديد ستفعل ما وصفته للتو:

public static IEnumerable<T> Exclude<T>
    (this IEnumerable<T> source, IEnumerable<T> items)
{
    foreach (T t in source)
        if (!items.Contains(t))
            yield return t;
}


nevermind، استخدم Enumerable.Except طريقة التمديد:

تنتج الفرق الفرعي للتسلسلين.

نصائح أخرى

إذا كنت تستطيع التكرار فوق المجموعات بالترتيب، فيمكنك ضمان السلوك O (N) (بدلا من "بدلا من" O (N) ولكن ربما O (N²) في أسوأ الحالات "التي لدى Hathset) من خلال التكرار من خلالها lockstep.

علي سبيل المثال:

//loop boilerplate
if(itemA < itemB) {
    itemA = a.next();
    continue;
}
if(itemA > itemB) {
    itemB = b.next();
    continue;
}
a.remove(itemA);

ستحتاج إلى إضافة فحص الحدود وغيرها من الغليان بنفسك.

قد تحصل على أداء أفضل من خلال تحويل SuperSet إلى Hashtable (O (n) عادة، ولكن بعد ذلك يسمح لك بإجراء عمليات البحث في وقت ثابت). ثم يمكنك التعداد فوق المجموعة الفرعية وتحقق مما إذا كان كل عنصر موجود في SuperSet. يجب أن تأخذ العملية بأكملها o (n) الذاكرة الإضافية و O (N) الوقت.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top