المحكمة الخاصة بلبنان فرز مجموعة فيها شروط النظام قد تغير

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

  •  04-07-2019
  •  | 
  •  

سؤال

لدي C++ المحكمة مع مجموعة مخصصة يأمر محددة.

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

ومع ذلك ، ما كنت فقط أدركت أن يأمر المسند يمكن أن تتغير مع مرور الوقت.

ويفترض العناصر في المجموعة ثم لم يعد في النظام.

حتى سؤالين حقا:

  1. هل هو مضر أن البنود عندئذ ؟ هل أنا على حق في القول بأن أسوأ ما يمكن أن يحدث هو أن إدخالات جديدة قد وضعت في المكان الخطأ (والتي في الواقع لا يمكن أن يعيش مع).أو أن هذا يسبب حوادث, فقدت المشاركات وما إلى ذلك ؟

  2. هل هناك طريقة "تحديث" ترتيب المجموعة ؟ يبدو أنك لا يمكن استخدام std::النوع() على مجموعة.أفضل ما يمكن أن تأتي مع إلقاء محتويات إلى درجة الحرارة حاوية وإعادة إضافتها.

أي أفكار ؟

شكرا

جون

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

المحلول

set يستخدم يأمر للبحث عن العناصر.إذا كنت إدراج ن البنود وفقا ordering1 وإدراج بند وفقا ordering2 مجموعة لا يمكن معرفة ما إذا كان هذا البند هو بالفعل في.

وسوف تنتهك فئة ثابتة أن كل عنصر هو في هناك مرة واحدة فقط.

لذلك لا الأذى.

نصائح أخرى

الطريقة الآمنة الوحيدة للقيام بذلك مع المحكمة الخاصة بلبنان هو خلق مجموعة جديدة مع تغير المسند.على سبيل المثال هل يمكن أن تفعل شيئا من هذا القبيل عندما كنت في حاجة لفرز مع مجموعة جديدة المسند:

std::set<int> newset( oldset.begin(), oldset.end(), NewPred() );

هذا هو في الواقع تنفيذ التابعة.
المحكمة الخاصة بلبنان التنفيذ و عادة ما يفترض المسند تستخدم لفرز مستقرة (على خلاف ذلك ، "فرز" لن تكون محددة).فمن الممكن على الأقل لبناء صالحة الخاصة بلبنان تنفيذ هذا تنسيقات القرص الصلب الخاص بك عند تغيير سلوك المسند سبيل المثال.

لذا, نعم, تحتاج إلى إعادة إدراج العناصر في مجموعة جديدة.

بدلا من ذلك, يمكنك بناء الخاصة بك الحاوية على سبيل المثالناقلات + النوع + lower_bound من أجل البحث الثنائية.ثم هل يمكن إعادة فرز عندما المسندات التغييرات في السلوك.

وأنا أتفق مع إجابات أخرى, أن هذا هو الذهاب الى كسر في بعض غريبة ومن الصعب تصحيح الطرق.إذا كنت تذهب التحديث الطريق ، ما عليك سوى أن تفعل نسخة مرة واحدة.إنشاء tmp مع مجموعة جديدة من الفرز استراتيجية ، إضافة كل عنصر من المجموعة الأصلية إلى tmp ثم لا

 orig.swap(tmp);

هذا سوف مبادلة الداخلية مجموعات.

كان هذا لي, أود أن ننتهي من ذلك في فئة جديدة أن يعالج كل التفاصيل, بحيث يمكنك تغيير تطبيقات حسب الحاجة.اعتمادا على الوصول إلى أنماط عدد مرات ترتيب التغيرات المذكورة سابقا ناقلات, نوع, lowerbound قد يكون الحل الأفضل.

إذا كنت تستطيع العيش مع مجموعة غير مرتبة ، ثم لماذا إضافتها إلى مجموعة في المقام الأول ؟

الحالة الوحيدة التي أستطيع أن أفكر من أين تريد فقط للتأكد من قائمة فريدة من نوعها عند إضافتها.إذا كان هذا هو الحال ثم هل يمكن استخدام مجموعة مؤقت لحماية الإضافات:

if (ts.insert (value).second) {
    // insertion took place
    realContainer.push_back (value);
}

البديل هو أن هذا يتوقف على كيف في كثير من الأحيان سوف يكون تعديل إدخالات في مجموعة, ربما يمكنك اختبار لمعرفة ما إذا كان سيكون دخول في موقع مختلف (باستخدام مجموعة مقارنة وظيفة) وأين موقف سوف تتحرك ثم قم بإزالة إدخال وإعادة إضافة واحدة جديدة.

الجميع أشار - وجود مجموعة غير مرتبة حقا رائحة سيئة - و أنا أيضا أعتقد أن من الممكن حصلت غير معرف سلوك وفقا الأمراض المنقولة جنسيا.

في حين أن هذا لا تعطيك ما تريده بالضبط ، دفعة::multi_index يعطيك وظائف مماثلة.بسبب طريقة عمل القوالب, أنك لن تكون قادرة على "تغيير" ترتيب المسند عن حاوية يتم تعيين في الحجر في وقت الترجمة ، إلا إذا كنت تستخدم فرز ناقلات أو شيئا من هذا القبيل ، حيث لك هي واحدة من الحفاظ على ثابتة و يمكن فرز ومع ذلك تريد في أي وقت معين.

Multi_index ومع ذلك يعطيك طريقة النظام مجموعة من العناصر استنادا إلى عدة يأمر المسندات في نفس الوقت.ثم يمكنك تحديد آراء الحاوية التي تتصرف مثل std::مجموعة أمرت المسند أن يهمك في ذلك الوقت.

هذا يمكن أن يسبب فقدان إدخالات عند البحث عن عنصر في set طلب المشغل يستخدم هذا يعني أنه إذا كان العنصر يوضع إلى يسار الجذر الآن يأمر المشغل إلى اليمين ثم هذا العنصر لم يعد يمكن العثور عليها.

هنا اختبار بسيط لك:

struct comparer : public std::binary_function<int, int, bool>
{
  static enum CompareType {CT_LESS, CT_GREATER} CompareMode;
  bool operator()(int lhs, int rhs) const
  {
    if(CompareMode == CT_LESS)
    {
      return lhs < rhs;
    }
    else
    {
      return lhs > rhs;
    }
  }
};

comparer::CompareType comparer::CompareMode = comparer::CT_LESS;

typedef std::set<int, comparer> is_compare_t;

void check(const is_compare_t &is, int v)
{
  is_compare_t::const_iterator it = is.find(v);
  if(it != is.end())
  {
    std::cout << "HAS " << v << std::endl;
  }
  else
  {
    std::cout << "ERROR NO " << v << std::endl;
  }
}

int main()
{
  is_compare_t is;
  is.insert(20);
  is.insert(5);
  check(is, 5);
  comparer::CompareMode = comparer::CT_GREATER;
  check(is, 5);
  is.insert(27);
  check(is, 27);
  comparer::CompareMode = comparer::CT_LESS;
  check(is, 5);
  check(is, 27);
  return 0;
}

لذا أساسا إذا كنت تنوي أن تكون قادرة على البحث العناصر التي تم إدراجها مرة واحدة يجب أن لا تغيير المسند المستخدمة في الإدراج والبحث.

مجرد متابعة:

أثناء تشغيل هذه التعليمات البرمجية Visual Studio C التصحيح المكتبات بدأ رمي الاستثناءات تشكو من أن "<"المشغل " باطل".

لذا فإنه لا يبدو أن تغيير نوع الطلب هو شيء سيء.شكرا للجميع!

1) الضارة - لا.يؤدي إلى حوادث - لا.الأسوأ هو في الواقع غير فرز مجموعة.

2) "منعش" سيكون نفس إعادة إضافة على أية حال!

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