290. EquivalenceRelationEqualityComparer

כזכור, EqualityComparer מאפשר לנו לתת התנהגות לפיה שני איברים נחשבים שווים.

קיים מודל מתמטי המתאר שקילות בין קבוצת אובייקטים הנקרא יחס שקילות.

זהו יחס R המקיים 3 תנאים:

  1. רפלקסיביות: a R a (כלומר a תמיד שקול לעצמו)
  2. סימטריות: אם a R b אזי גם b R a (כלומר שקילות היא סימטרית)
  3. טרנזטיביות: אם a R b וגם b R c אזי a R c.

מושג זה מתאר בצורה פשוטה מהי שקילות.

נוכל לייצג את זה באמצעות מבנה הבודק האם שני איברים שקולים:

1
HashSet<KeyValuePair<T, T>>

מבנה זה אומר שa שקול לb אם"ם הזוג new KeyValuePair<T, T>(a, b) נמצא בו.

מאחר והיחס סימטרי, נרצה להשתמש בSymmetricEqualityComparer שראינו פעם שעברה. זה יבטיח שאם $ a $ שקול ל$ b $ אזי $ b $ שקול ל$ a $:

1
HashSet<KeyValuePair<T, T>> equivalenceRelation = new HashSet<KeyValuePair<T,T>>(new SymmetricEqualityComparer<T>());

נוכל ליצור ממבנה זה EqualityComparer מתאים:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class EquivalenceRelationEqualityComparer<T> : IEqualityComparer<T>
{
private readonly HashSet<KeyValuePair<T, T>> mEquivalenceRelation;
public EquivalenceRelationEqualityComparer(HashSet<KeyValuePair<T, T>> equivalenceRelation)
{
mEquivalenceRelation = equivalenceRelation;
}
public bool Equals(T x, T y)
{
if (ReferenceEquals(x, y))
{
return true;
}
return mEquivalenceRelation.Contains(new KeyValuePair<T, T>(x, y));
}
public int GetHashCode(T obj)
{
return 0;
}
}

שימו לב שאין לנו דרך לתת HashCode סביר כי אנחנו לא יודעים לבחור נציג קנוני ליחס השקילות, אבל למקומות בהם לא משתמשים בGetHashCode, או לחלופין במקומות בהם יש מספר קטן של איברים, זה יכול להיות מספיק שימושי.

המשך יום ששקול ליום מצוין.

שתף