المشغل <والطلب ضعيف صارم
-
13-09-2019 - |
سؤال
كيفية تحديد 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);
عدل