سؤال

كيفية تحديد operator< على n-tuple (على سبيل المثال على 3 tuple) بحيث ترضي ترتيب ضعيف صارم مفهوم ؟ أعلم أن مكتبة Boost تحتوي على فئة Tuple مع تعريفها بشكل صحيح operator< ولكن لبعض الأسباب لا أستطيع استخدامها.

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

المحلول

if (a1 < b1)
  return true;
if (b1 < a1)
  return false;

// a1==b1: continue with element 2
if (a2 < b2)
  return true;
if (b2 < a2)
  return false;

// a2 == b2: continue with element 3
if (a3 < b3)
  return true;
return false; // early out

هذا الطلبات العناصر بمقدار A1 كونها أكثر سيكلية و A3 الأقل أهمية.

يمكن أن تستمر هذا في إيناع إعلاني مستمرا، يمكنك أيضا تطبيقه على تطبيقه على متجه T، مما يكرر على مقارنات A [i] <a [i + 1] / a [i + 1] <a [i]. سيكون تعبيرا بديلا عن الخوارزمية "تخطي بينما يساوي، ثم قارن":

while (i<count-1 && !(a[i] < a[i+1]) && !(a[i+1] < a[i])
  ++i;
return i < count-1 && a[i] < a[i+1];

بالطبع، إذا كانت المقارنة باهظة الثمن، فقد ترغب في التخزين المؤقت نتيجة المقارنة.


تحرير] إزالة رمز خاطئ


تحرير] إذا كان أكثر من مجرد operator< متاح، أميل إلى استخدام النمط

if (a1 != b1)
  return a1 < b1;

if (a2 != b2)
  return a2 < b2;

...

نصائح أخرى

ترتيب ضعيف صارم

هذا هو مصطلح رياضي لتحديد العلاقة بين كائنين.
تعريفه هو:

اثنين من الكائنات X و Y تعادل ما يعادلها إذا كانت كل من F (x و y) و f (y، x) خاطئة. لاحظ أن الكائن هو دائما (بواسطة Infreflexivity Invariant) يعادل نفسه.

من حيث C ++ هذا يعني إذا كان لديك كائنتين لنوع معين، فيجب عليك إرجاع القيم التالية بالمقارنة مع المشغل <.

X    a;
X    b;

Condition:                  Test:     Result
a is equivalent to b:       a < b     false
a is equivalent to b        b < a     false

a is less than b            a < b     true
a is less than b            b < a     false

b is less than a            a < b     false
b is less than a            b < a     true

كيف تحدد ما يعادلها / أقل يعتمد تماما على نوع الكائن الخاص بك.

تعريف رسمي:
ترتيب ضعيف صارم

علوم الكمبيوتر:
ترتيب ضعيف صارم

كيف يتعلق بالمشغلين:
المقارنة

... إجابة جديدة لسؤال قديم للغاية، ولكن الإجابة الحالية تفوت الحل السهل من C ++ 11 ...

C ++ 11 الحل

يوفر C ++ 11 وما بعده std::tuple<T...>, ، والتي يمكنك استخدامها لتخزين البيانات الخاصة بك. tupleلها مطابقة operator< في البداية يقارن في البداية عن عنصر اليسار، ثم يعمل على طول tuple حتى الوضوح النتيجة. هذا مناسب لتوفير ترتيب ضعيف صارم المتوقع من قبل على سبيل المثال std::set و std::map.

إذا كان لديك بيانات في بعض المتغيرات الأخرى (مثل الحقول في struct)، يمكنك حتى استخدام std::tie() لإخارة tuple المراجع, ، والتي يمكن بعد ذلك مقارنة مع آخر هذا tuple. هذا يجعل من السهل الكتابة operator< لحقول بيانات عضو محددة في تعريف المستخدم class/struct يكتب:

struct My_Struct
{
    int a_;
    double b_;
    std::string c_;
};

bool operator<(const My_Struct& lhs, const My_Struct& rhs)
{
    return std::tie(lhs.a_, lhs.b_, lhs.c_) < std::tie(rhs.a_, rhs.b_, rhs.c_);
}

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

يجب أن يكون التدفق الأساسي على غرار: إذا كانت عناصر KTH مختلفة، فإرجاع أصغر آخر يذهب إلى العنصر التالي. وبعد الكود التالي يفترض لك لا لديك تعزز tuple خلاف ذلك سوف تستخدم get<N>(tuple) وليس لديك مشكلة لتبدأ.

if (lhs.first != rhs.first)
    return lhs.first < rhs.first;                
if (lhs.second != rhs.second)
    return lhs.second< rhs.second;
return lhs.third < rhs.third;

حتى إذا لم تتمكن من استخدام إصدار دفعة، يجب أن تكون قادرا على نيك الكود. أنا متحرك هذا من STD :: Pair - ستكون 3 Tuple مماثلة مما أعتقد.

return (_Left.first < _Right.first ||
        !(_Right.first < _Left.first) && _Left.second < _Right.second);

عدل

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