Exemple #1
0
        /// <summary>
        /// Get depth of the tree.
        /// </summary>
        /// <typeparam name="T">The type of value the node contains.</typeparam>
        /// <param name="tree">A tree to calculte depth.</param>
        /// <returns>The depth of the tree.</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="tree"/> is <see langword="null"/>.</exception>
        public static int GetDepth <T>(this ITreeBase <T> tree)
        {
            int GetDepthInternal(ITreeBase <T> node, int depth)
            {
                int result = depth;

                foreach (ITreeBase <T> child in node)
                {
                    int tempDepth = GetDepthInternal(child, depth + 1);
                    if (tempDepth > result)
                    {
                        result = tempDepth;
                    }
                }
                return(result);
            }

            switch (tree ?? throw ExceptionHelper.ArgumentNull(nameof(tree)))
            {
            case IBinaryTree <T> binaryTree:
                return(GetDepthBinary(binaryTree));

            default:
                return(GetDepthInternal(tree, 1));
            }
        }
Exemple #2
0
 /// <summary>
 /// Initialize an instance of <see cref="MultiMap{TKey1, TKey2}"/>.
 /// </summary>
 /// <param name="map">Existed map.</param>
 /// <param name="comparer1">Comparer of key1.</param>
 /// <param name="comparer2">Comparer of key2.</param>
 /// <exception cref="ArgumentNullException">When <paramref name="map"/> is <see langword="null"/>.</exception>
 public MultiMap(IMultiMap <TKey1, TKey2> map, IEqualityComparer <TKey1> comparer1, IEqualityComparer <TKey2> comparer2)
     : this(map?.Count ?? 0, comparer1, comparer2)
 {
     foreach (var item in map ?? throw ExceptionHelper.ArgumentNull(nameof(map)))
     {
         Add(item.Key1, item.Key2);
     }
 }
Exemple #3
0
 /// <summary>
 /// Inserts an elenemt with specified key1 and key2.
 /// </summary>
 /// <param name="key1">The specified key1.</param>
 /// <param name="key2">The specified key2.</param>
 /// <param name="add">Determines whether this is an add method.</param>
 /// <returns><see langword="true"/> if inserts successfully; otherwise, <see langword="false"/>.</returns>
 /// <exception cref="ArgumentNullException">When <paramref name="key1"/> or <paramref name="key2"/> is <see langword="null"/> and <paramref name="add"/> is <see langword="true"/>.</exception>
 /// <exception cref="ArgumentException">When the specified element is existed and <paramref name="add"/> is <see langword="true"/>.</exception>
 private bool Insert(TKey1 key1, TKey2 key2, bool add)
 {
     if (key1 == null)
     {
         if (add)
         {
             throw ExceptionHelper.ArgumentNull(nameof(key1));
         }
         else
         {
             return(false);
         }
     }
     if (key2 == null)
     {
         if (add)
         {
             throw ExceptionHelper.ArgumentNull(nameof(key2));
         }
         else
         {
             return(false);
         }
     }
     if (dic.Contains(key1))
     {
         if (dic[key1].Contains(key2))
         {
             if (add)
             {
                 throw ExceptionHelper.PairExisted();
             }
             else
             {
                 return(false);
             }
         }
         else
         {
             dic.Add(key1, key2);
         }
     }
     else
     {
         dic.Add(key1, key2);
     }
     if (rev.Contains(key2))
     {
         rev.Add(key2, key1);
     }
     else
     {
         rev.Add(key2, key1);
     }
     return(true);
 }
Exemple #4
0
        /// <summary>
        /// Get an <see cref="IEnumerable{T}"/> with order of depth-first-search.
        /// </summary>
        /// <typeparam name="T">The type of value the node contains.</typeparam>
        /// <param name="tree">A tree to enumerate.</param>
        /// <returns>An <see cref="IEnumerable{T}"/> with order of depth-first-search.</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="tree"/> is <see langword="null"/>.</exception>
        public static IEnumerable <ITreeBase <T> > AsDFSEnumerable <T>(this ITreeBase <T> tree)
        {
            switch (tree ?? throw ExceptionHelper.ArgumentNull(nameof(tree)))
            {
            case IBinaryTree <T> binaryTree:
                return(AsPreOrderEnumerableIterator(binaryTree));

            default:
                return(AsDFSEnumerableIterator(tree));
            }
        }
Exemple #5
0
 /// <summary>
 /// Determines whether the <see cref="MultiMap{TKey1, TKey2}"/> contains the element with specified key1 and key2.
 /// </summary>
 /// <param name="key1">The specified key1.</param>
 /// <param name="key2">The specified key2.</param>
 /// <returns><see langword="true"/> if it contains; otherwise, <see langword="false"/>.</returns>
 public bool Contains(TKey1 key1, TKey2 key2)
 {
     if (key1 == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(key1));
     }
     if (key2 == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(key2));
     }
     return(dic.Contains(key1) && dic[key1].Contains(key2));
 }
Exemple #6
0
 /// <summary>
 /// Get an <see cref="IEnumerable{T}"/> with order of depth-first-search.
 /// </summary>
 /// <typeparam name="T">The type of vertex.</typeparam>
 /// <param name="graph">The graph to enumerate.</param>
 /// <param name="root">The first vertex to enumerate.</param>
 /// <returns>An <see cref="IEnumerable{T}"/> with order of depth-first-search.</returns>
 /// <exception cref="ArgumentNullException">When <paramref name="graph"/> is <see langword="null"/>.</exception>
 /// <exception cref="KeyNotFoundException">When <paramref name="root"/> is not contained in the graph.</exception>
 public static IEnumerable <T> AsDFSEnumerable <T>(this IGraph <T> graph, T root)
 {
     if (graph == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(graph));
     }
     if (!graph.Contains(root))
     {
         throw ExceptionHelper.KeyNotFound();
     }
     return(AsDFSEnumerableIterator(graph, root));
 }
Exemple #7
0
        /// <summary>
        /// Determines whether a vertex is in a loop of an instance of <see cref="IGraph{T}"/>.
        /// </summary>
        /// <typeparam name="T">The type of vertex.</typeparam>
        /// <param name="graph">The graph to enumerate.</param>
        /// <param name="vertex">The specified vertex.</param>
        /// <returns><see langword="true"/> if the <paramref name="vertex"/> is in a loop; otherwise, <see langword="false"/>.</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="graph"/> is <see langword="null"/>.</exception>
        /// <exception cref="KeyNotFoundException">When <paramref name="vertex"/> is not contained in the graph.</exception>
        public static bool IsInLoop <T>(this IGraph <T> graph, T vertex)
        {
            if (graph == null)
            {
                throw ExceptionHelper.ArgumentNull(nameof(graph));
            }
            if (!graph.Contains(vertex))
            {
                throw ExceptionHelper.KeyNotFound();
            }
            Stack <T>   nodes   = new Stack <T>();
            HashSet <T> visited = new HashSet <T>();

            nodes.Push(vertex);
            T last = default;

            while (nodes.Count != 0)
            {
                T current;
                do
                {
                    if (nodes.Count == 0)
                    {
                        goto ret;
                    }
                    current = nodes.Pop();
                }while (visited.Contains(current));
                visited.Add(current);
                if (graph.TryGetHeads(current, out var heads))
                {
                    foreach (var child in heads)
                    {
                        if (!visited.Contains(child))
                        {
                            nodes.Push(child);
                        }
                        else if (EqualityComparer <T> .Default.Equals(vertex, child) && !EqualityComparer <T> .Default.Equals(last, child))
                        {
                            return(true);
                        }
                    }
                }
                last = current;
            }
ret:
            return(false);
        }
Exemple #8
0
 /// <summary>
 /// Copies the entire <see cref="Map{TKey1, TKey2}"/> to a compatible one-dimensional array, starting at the specified index of the target array.
 /// </summary>
 /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="Map{TKey1, TKey2}"/>. The <see cref="Array"/> must have zero-based indexing.</param>
 /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
 /// <exception cref="ArgumentNullException">When <paramref name="array"/> is <see langword="null"/>.</exception>
 /// <exception cref="ArgumentOutOfRangeException">When <paramref name="arrayIndex"/> is smaller than zero or larger than the length of <paramref name="array"/>.</exception>
 /// <exception cref="ArgumentException">When <paramref name="array"/> is too small.</exception>
 public void CopyTo(KeyPair <TKey1, TKey2>[] array, int arrayIndex)
 {
     if (array == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(array));
     }
     if (arrayIndex < 0 || arrayIndex > array.Length)
     {
         throw ExceptionHelper.ArgumentOutOfRange(nameof(arrayIndex));
     }
     if (array.Length - arrayIndex < dic.Count)
     {
         throw ExceptionHelper.ArrayTooSmall();
     }
     foreach (var item in this)
     {
         array[arrayIndex++] = item;
     }
 }
Exemple #9
0
 /// <summary>
 /// Copies the entire <see cref="Map{TKey1, TKey2}"/> to a compatible one-dimensional array, starting at the specified index of the target array.
 /// </summary>
 /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="Map{TKey1, TKey2}"/>. The <see cref="Array"/> must have zero-based indexing.</param>
 /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
 /// <exception cref="ArgumentNullException">When <paramref name="array"/> is <see langword="null"/>.</exception>
 /// <exception cref="ArgumentOutOfRangeException">When <paramref name="arrayIndex"/> is smaller than zero or larger than the length of <paramref name="array"/>.</exception>
 /// <exception cref="ArgumentException">When <paramref name="array"/> is too small.</exception>
 public void CopyTo(KeyPair <TKey1, TKey2>[] array, int arrayIndex)
 {
     if (array == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(array));
     }
     if (arrayIndex < 0 || arrayIndex > array.Length)
     {
         throw ExceptionHelper.ArgumentOutOfRange(nameof(arrayIndex));
     }
     if (array.Length - arrayIndex < dic.Count)
     {
         throw ExceptionHelper.ArrayTooSmall();
     }
     foreach (var pair in dic)
     {
         array[arrayIndex] = new KeyPair <TKey1, TKey2>(pair.Key, pair.Value);
         arrayIndex++;
     }
 }
Exemple #10
0
 /// <summary>
 /// Copies the entire <see cref="Collection{T}"/> to a compatible one-dimensional <see cref="Array"/>, starting at the specified index of the target array.
 /// </summary>
 /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="Collection{T}"/>. The <see cref="Array"/> must have zero-based indexing.</param>
 /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
 public void CopyTo(TElement[] array, int arrayIndex)
 {
     if (array == null)
     {
         throw ExceptionHelper.ArgumentNull(nameof(array));
     }
     if (arrayIndex < 0)
     {
         throw ExceptionHelper.ArgumentOutOfRange(nameof(arrayIndex));
     }
     if (arrayIndex > array.Length)
     {
         throw ExceptionHelper.ArgumentOutOfRange(nameof(arrayIndex));
     }
     if (array.Length - arrayIndex < collection.Count)
     {
         throw ExceptionHelper.ArrayTooSmall();
     }
     collection.CopyTo(array, arrayIndex);
 }
Exemple #11
0
        /// <summary>
        /// Initialize a new instance of <see cref="Lookup{TKey, TElement}"/> class.
        /// </summary>
        /// <param name="lookup">A lookup source.</param>
        /// <param name="comparer">The comparer of the keys.</param>
        public Lookup(ILookup <TKey, TElement> lookup, IEqualityComparer <TKey> comparer)
        {
            switch (lookup ?? throw ExceptionHelper.ArgumentNull(nameof(lookup)))
            {
            case Lookup <TKey, TElement> lkp:
                dic = new Dictionary <TKey, Grouping <TKey, TElement> >(lkp.dic, comparer);
                break;

            default:
                dic = new Dictionary <TKey, Grouping <TKey, TElement> >(lookup.Count, comparer);
                foreach (var grouping in lookup)
                {
                    foreach (var item in grouping)
                    {
                        Add(grouping.Key, item);
                    }
                }
                break;
            }
        }
Exemple #12
0
        /// <summary>
        /// Get <see cref="MultiMap{TKey1, TKey2}"/> from <see cref="IEnumerable{TSource}"/>.
        /// </summary>
        /// <typeparam name="TSource">Type of elements of <paramref name="source"/>.</typeparam>
        /// <typeparam name="TKey1">Type of key1.</typeparam>
        /// <typeparam name="TKey2">Type of key2.</typeparam>
        /// <param name="source">The source.</param>
        /// <param name="key1Selector">Selector of key1.</param>
        /// <param name="key2Selector">Selector of key2.</param>
        /// <param name="comparer1">Comparer of key1.</param>
        /// <param name="comparer2">Comparer of key2.</param>
        /// <returns>An instance of <see cref="MultiMap{TKey1, TKey2}"/>.</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="source"/> or <paramref name="key1Selector"/> or <paramref name="key2Selector"/> is <see langword="null"/>.</exception>
        public static MultiMap <TKey1, TKey2> ToMultiMap <TSource, TKey1, TKey2>(this IEnumerable <TSource> source, Func <TSource, TKey1> key1Selector, Func <TSource, TKey2> key2Selector, IEqualityComparer <TKey1> comparer1, IEqualityComparer <TKey2> comparer2)
        {
            if (source == null)
            {
                throw ExceptionHelper.ArgumentNull(nameof(source));
            }
            if (key1Selector == null)
            {
                throw ExceptionHelper.ArgumentNull(nameof(key1Selector));
            }
            if (key2Selector == null)
            {
                throw ExceptionHelper.ArgumentNull(nameof(key2Selector));
            }
            MultiMap <TKey1, TKey2> lookup = new MultiMap <TKey1, TKey2>(comparer1, comparer2);

            foreach (TSource item in source)
            {
                lookup.Add(key1Selector(item), key2Selector(item));
            }
            return(lookup);
        }
Exemple #13
0
 public IMapDebugView(IMap <K, V> map)
 {
     this.map = map ?? throw ExceptionHelper.ArgumentNull(nameof(map));
 }
Exemple #14
0
 public ICountableGroupingDebugView(ICountableGrouping <K, V> grouping)
 {
     this.grouping = grouping ?? throw ExceptionHelper.ArgumentNull(nameof(grouping));
 }
Exemple #15
0
 public IMutableLookupDebugView(IMutableLookup <K, V> lookup)
 {
     this.lookup = lookup ?? throw ExceptionHelper.ArgumentNull(nameof(lookup));
 }