?? orderedbag.cs
字號:
{
T item;
CheckEmpty();
tree.LastItemInRange(tree.EntireRangeTester, out item);
return item;
}
/// <summary>
/// Removes the first item in the bag. This is also the smallest
/// item in the bag.
/// </summary>
/// <remarks>RemoveFirst() takes time O(log N), where N is the number of items in the bag.</remarks>
/// <returns>The item that was removed, which was the smallest item in the bag. </returns>
/// <exception cref="InvalidOperationException">The bag is empty.</exception>
public T RemoveFirst()
{
CheckEmpty();
T item;
tree.DeleteItemFromRange(tree.EntireRangeTester, true, out item);
return item;
}
/// <summary>
/// Removes the last item in the bag. This is also the largest item in the bag.
/// </summary>
/// <remarks>RemoveLast() takes time O(log N), where N is the number of items in the bag.</remarks>
/// <returns>The item that was removed, which was the largest item in the bag. </returns>
/// <exception cref="InvalidOperationException">The bag is empty.</exception>
public T RemoveLast()
{
CheckEmpty();
T item;
tree.DeleteItemFromRange(tree.EntireRangeTester, false, out item);
return item;
}
#endregion
#region Set operations
/// <summary>
/// Check that this bag and another bag were created with the same comparison
/// mechanism. Throws exception if not compatible.
/// </summary>
/// <param name="otherBag">Other bag to check comparision mechanism.</param>
/// <exception cref="InvalidOperationException">If otherBag and this bag don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
private void CheckConsistentComparison(OrderedBag<T> otherBag)
{
if (otherBag == null)
throw new ArgumentNullException("otherBag");
if (!object.Equals(comparer, otherBag.comparer))
throw new InvalidOperationException(Strings.InconsistentComparisons);
}
/// <summary>
/// Determines if this bag is a superset of another bag. Neither bag is modified.
/// This bag is a superset of <paramref name="otherBag"/> if every element in
/// <paramref name="otherBag"/> is also in this bag, at least the same number of
/// times.
/// </summary>
/// <remarks>IsSupersetOf is computed in time O(M log N), where M is the size of the
/// <paramref name="otherSet"/>, and N is the size of the this set.</remarks>
/// <param name="otherBag">OrderedBag to compare to.</param>
/// <returns>True if this is a superset of <paramref name="otherBag"/>.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public bool IsSupersetOf(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
if (otherBag.Count > this.Count)
return false; // Can't be a superset of a bigger bag
// Check each item in the other bag to make sure it is in this bag.
foreach (T item in otherBag.DistinctItems()) {
if (this.NumberOfCopies(item) < otherBag.NumberOfCopies(item))
return false;
}
return true;
}
/// <summary>
/// Determines if this bag is a proper superset of another bag. Neither bag is modified.
/// This bag is a proper superset of <paramref name="otherBag"/> if every element in
/// <paramref name="otherBag"/> is also in this bag, at least the same number of
/// times. Additional, this bag must have strictly more items than <paramref name="otherBag"/>.
/// </summary>
/// <remarks>IsProperSupersetOf is computed in time O(M log N), where M is the number of unique items in
/// <paramref name="otherBag"/>.</remarks>
/// <param name="otherBag">OrderedBag to compare to.</param>
/// <returns>True if this is a proper superset of <paramref name="otherBag"/>.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public bool IsProperSupersetOf(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
if (otherBag.Count >= this.Count)
return false; // Can't be a proper superset of a bigger or equal set
return IsSupersetOf(otherBag);
}
/// <summary>
/// Determines if this bag is a subset of another bag. Neither bag is modified.
/// This bag is a subset of <paramref name="otherBag"/> if every element in this bag
/// is also in <paramref name="otherBag"/>, at least the same number of
/// times.
/// </summary>
/// <remarks>IsSubsetOf is computed in time O(N log M), where M is the size of the
/// <paramref name="otherBag"/>, and N is the size of the this bag.</remarks>
/// <param name="otherBag">OrderedBag to compare to.</param>
/// <returns>True if this is a subset of <paramref name="otherBag"/>.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public bool IsSubsetOf(OrderedBag<T> otherBag)
{
return otherBag.IsSupersetOf(this);
}
/// <summary>
/// Determines if this bag is a proper subset of another bag. Neither bag is modified.
/// This bag is a subset of <paramref name="otherBag"/> if every element in this bag
/// is also in <paramref name="otherBag"/>, at least the same number of
/// times. Additional, this bag must have strictly fewer items than <paramref name="otherBag"/>.
/// </summary>
/// <remarks>IsSubsetOf is computed in time O(N log M), where M is the size of the
/// <paramref nameb="otherBag"/>, and N is the size of the this bag.</remarks>
/// <param name="otherBag">OrderedBag to compare to.</param>
/// <returns>True if this is a proper subset of <paramref name="otherBag"/>.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public bool IsProperSubsetOf(OrderedBag<T> otherBag)
{
return otherBag.IsProperSupersetOf(this);
}
/// <summary>
/// Determines if this bag is disjoint from another bag. Two bags are disjoint
/// if no item from one set is equal to any item in the other bag.
/// </summary>
/// <remarks>
/// <para>The answer is computed in time O(N), where N is the size of the smaller set.</para>
/// </remarks>
/// <param name="otherBag">Bag to check disjointness with.</param>
/// <returns>True if the two bags are disjoint, false otherwise.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
public bool IsDisjointFrom(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
OrderedBag<T> smaller, larger;
if (otherBag.Count > this.Count) {
smaller = this; larger = otherBag;
}
else {
smaller = otherBag; larger = this;
}
foreach (T item in smaller) {
if (larger.Contains(item))
return false;
}
return true;
}
/// <summary>
/// Determines if this bag is equal to another bag. This bag is equal to
/// <paramref name="otherBag"/> if they contain the same items, each the
/// same number of times.
/// </summary>
/// <remarks>IsEqualTo is computed in time O(N), where N is the number of items in
/// this bag.</remarks>
/// <param name="otherBag">OrderedBag to compare to</param>
/// <returns>True if this bag is equal to <paramref name="otherBag"/>, false otherwise.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
public bool IsEqualTo(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
// Must be the same size.
if (otherBag.Count != this.Count)
return false;
// Since both bags are ordered, we can simply compare items in order.
using (IEnumerator<T> enum1 = this.GetEnumerator(), enum2 = otherBag.GetEnumerator()) {
bool continue1, continue2;
for (; ; ) {
continue1 = enum1.MoveNext(); continue2 = enum2.MoveNext();
if (!continue1 || !continue2)
break;
if (comparer.Compare(enum1.Current, enum2.Current) != 0)
return false; // the two items are not equal.
}
// If both continue1 and continue2 are false, we reached the end of both sequences at the same
// time and found success. If one is true and one is false, the sequences were of difference lengths -- failure.
return (continue1 == continue2);
}
}
/// <summary>
/// Computes the union of this bag with another bag. The union of two bags
/// is all items from both of the bags. If an item appears X times in one bag,
/// and Y times in the other bag, the union contains the item Maximum(X,Y) times. This bag receives
/// the union of the two bags, the other bag is unchanged.
/// </summary>
/// <remarks>
/// <para>The union of two bags is computed in time O(M + N log M), where M is the size of the
/// larger bag, and N is the size of the smaller bag.</para>
/// </remarks>
/// <param name="otherBag">Bag to union with.</param>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public void UnionWith(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
T previous = default(T);
bool atBeginning = true;
int copiesInThis = 0, copiesInOther = 0;
// Enumerate each of the items in the other bag. Add items that need to be
// added to this bag.
// CONSIDER: may be able to improve this algorithm if otherBag is larger than this bag.
foreach (T item in otherBag) {
if (atBeginning || comparer.Compare(item, previous) != 0) {
copiesInThis = this.NumberOfCopies(item);
copiesInOther = 1;
}
else {
++copiesInOther;
}
if (copiesInOther > copiesInThis)
this.Add(item);
previous = item;
atBeginning = false;
}
}
/// <summary>
/// Computes the union of this bag with another bag. The union of two bags
/// is all items from both of the bags. If an item appears X times in one bag,
/// and Y times in the other bag, the union contains the item Maximum(X,Y) times. A new bag is
/// created with the union of the bags and is returned. This bag and the other bag
/// are unchanged.
/// </summary>
/// <remarks>
/// <para>The union of two bags is computed in time O(M + N log M), where M is the size of the
/// larger bag, and N is the size of the smaller bag.</para>
/// </remarks>
/// <param name="otherBag">Bag to union with.</param>
/// <returns>The union of the two bags.</returns>
/// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
/// <exception cref="ArgumentNullException"><paramref name="otherBag"/> is null.</exception>
public OrderedBag<T> Union(OrderedBag<T> otherBag)
{
CheckConsistentComparison(otherBag);
OrderedBag<T> smaller, larger, result;
if (otherBag.Count > this.Count) {
smaller = this; larger = otherBag;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -