예제 #1
0
        /// <summary>
        /// Computes the difference of this bag with another bag. The difference of these two bags
        /// is all items that appear in this bag, but not in <paramref name="otherBag"/>. If an item appears X times in this bag,
        /// and Y times in the other bag, the difference contains the item X - Y times (zero times if Y >= X). This bag receives
        /// the difference of the two bags; the other bag is unchanged.
        /// </summary>
        /// <remarks>
        /// <para>The difference of two bags is computed in time O(M), where M is the size of the
        /// other bag.</para>
        /// </remarks>
        /// <param name="otherBag">Bag to difference with.</param>
        /// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
        public void DifferenceWith(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            if (this == otherBag)
            {
                Clear();
                return;
            }

            int copiesInThis, copiesInOther, copies;

            // Enumerate each of the items in the other bag. Remove items that need to be
            // removed from this bag.
            foreach (T item in otherBag.DistinctItems())
            {
                copiesInThis  = this.NumberOfCopies(item);
                copiesInOther = otherBag.NumberOfCopies(item);
                copies        = copiesInThis - copiesInOther;
                if (copies < 0)
                {
                    copies = 0;
                }

                ChangeNumberOfCopies(item, copies);
            }
        }
예제 #2
0
        /// <summary>
        /// Computes the symmetric difference of this bag with another bag. The symmetric difference of two bags
        /// is all items that appear in either of the bags, but not both. If an item appears X times in one bag,
        /// and Y times in the other bag, the symmetric difference contains the item AbsoluteValue(X - Y) times. This bag receives
        /// the symmetric difference of the two bags; the other bag is unchanged.
        /// </summary>
        /// <remarks>
        /// <para>The symmetric difference of two bags is computed in time O(M + N), 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 symmetric difference with.</param>
        /// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
        public void SymmetricDifferenceWith(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            if (this == otherBag)
            {
                Clear();
                return;
            }

            int copiesInThis, copiesInOther, copies;

            // Enumerate each of the items in the other bag. Add items that need to be
            // added to this bag.
            foreach (T item in otherBag.DistinctItems())
            {
                copiesInThis  = this.NumberOfCopies(item);
                copiesInOther = otherBag.NumberOfCopies(item);
                copies        = Math.Abs(copiesInThis - copiesInOther);

                if (copies != copiesInThis)
                {
                    ChangeNumberOfCopies(item, copies);
                }
            }
        }
예제 #3
0
        /// <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), where M is the number of unique items in
        /// <paramref name="otherBag"/>.</remarks>
        /// <param name="otherBag">Bag 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>
        public bool IsSupersetOf(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            if (otherBag.Count > this.Count)
            {
                return(false);     // Can't be a superset of a bigger set
            }
            // Check each item in the other set to make sure it is in this set.
            foreach (T item in otherBag.DistinctItems())
            {
                if (this.NumberOfCopies(item) < otherBag.NumberOfCopies(item))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Determines if this bag is equal to another bag. This bag is equal to
        /// <paramref name="otherBag"/> if they contain the same number of
        /// of copies of equal elements.
        /// </summary>
        /// <remarks>IsSupersetOf is computed in time O(N), where N is the number of unique items in
        /// this bag.</remarks>
        /// <param name="otherBag">Bag 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(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            // Must be the same size.
            if (otherBag.Count != this.Count)
            {
                return(false);
            }

            // Check each item to make sure it is in this set the same number of times.
            foreach (T item in otherBag.DistinctItems())
            {
                if (this.NumberOfCopies(item) != otherBag.NumberOfCopies(item))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
        /// <summary>
        /// Computes the sum of this bag with another bag. The sum 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 sum contains the item (X+Y) times. This bag receives
        /// the sum of the two bags, the other bag is unchanged.
        /// </summary>
        /// <remarks>
        /// <para>The sum of two bags is computed in time O(M), where M is the size of the
        /// other bag..</para>
        /// </remarks>
        /// <param name="otherBag">Bag to sum with.</param>
        /// <exception cref="InvalidOperationException">This bag and <paramref name="otherBag"/> don't use the same method for comparing items.</exception>
        public void SumWith(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            if (this == otherBag)
            {
                // Not very efficient, but an uncommon case.
                AddMany(otherBag);
                return;
            }

            int copiesInThis, copiesInOther;

            // Enumerate each of the items in the other bag. Add items that need to be
            // added to this bag.
            foreach (T item in otherBag.DistinctItems())
            {
                copiesInThis  = this.NumberOfCopies(item);
                copiesInOther = otherBag.NumberOfCopies(item);

                ChangeNumberOfCopies(item, copiesInThis + copiesInOther);
            }
        }
예제 #6
0
        /// <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), where M and N are the size of the
        /// two bags.</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>
        public void UnionWith(Bag <T> otherBag)
        {
            CheckConsistentComparison(otherBag);

            if (otherBag == this)
            {
                return;             // Nothing to do
            }
            int copiesInThis, copiesInOther;

            // Enumerate each of the items in the other bag. Add items that need to be
            // added to this bag.
            foreach (T item in otherBag.DistinctItems())
            {
                copiesInThis  = this.NumberOfCopies(item);
                copiesInOther = otherBag.NumberOfCopies(item);

                if (copiesInOther > copiesInThis)
                {
                    ChangeNumberOfCopies(item, copiesInOther);
                }
            }
        }