Пример #1
0
        /// <summary>
        ///   Enumerates all possible value permutations for a given array.
        /// </summary>
        ///
        /// <param name="values">The array whose permutations need to be generated</param>.
        /// <param name="inPlace">
        ///   If set to true, the different generated permutations will be stored in
        ///   the same array, thus preserving memory. However, this may prevent the
        ///   samples from being stored in other locations without having to clone
        ///   them. If set to false, a new memory block will be allocated for each
        ///   new object in the sequence.</param>
        ///
        /// <example>
        /// <code>
        ///   // Let's say we would like to generate all possible permutations
        ///   // of the elements (1, 2, 3). In order to enumerate all those
        ///   // permutations, we can use:
        ///
        ///   int[] values = { 1, 2, 3 };
        ///
        ///   foreach (int[] permutation in Combinatorics.Permutations(values))
        ///   {
        ///       // The permutations will be generated in the following order:
        ///       //
        ///       //   { 1, 3, 2 };
        ///       //   { 2, 1, 3 };
        ///       //   { 2, 3, 1 };
        ///       //   { 3, 1, 2 };
        ///       //   { 3, 2, 1 };
        ///       //
        ///   }
        /// </code>
        /// </example>
        ///
        public static IEnumerable <T[]> Permutations <T>(T[] values, bool inPlace = false)
        {
            T[] current = new T[values.Length];

            yield return(inPlace ? values : (T[])values.Clone());

            int[] idx = Matrix.Indices(0, values.Length);

            int j, l;

            while (true)
            {
                for (j = values.Length - 2; j >= 0; j--)
                {
                    if (idx[j + 1] > idx[j])
                    {
                        break;
                    }
                }

                if (j == -1)
                {
                    yield break;
                }

                for (l = values.Length - 1; l > j; l--)
                {
                    if (idx[l] > idx[j])
                    {
                        break;
                    }
                }

                int temp = idx[j];
                idx[j] = idx[l];
                idx[l] = temp;

                for (int i = j + 1; i < idx.Length; i++)
                {
                    if (i > idx.Length - i + j)
                    {
                        break;
                    }
                    temp   = idx[i];
                    idx[i] = idx[idx.Length - i + j];
                    idx[idx.Length - i + j] = temp;
                }

                for (int i = 0; i < values.Length; i++)
                {
                    current[i] = values[idx[i]];
                }

                yield return(inPlace ? current : (T[])current.Clone());
            }
        }
Пример #2
0
        /// <summary>
        ///   Enumerates all possible value permutations for
        ///   a given array.
        /// </summary>
        ///
        public static IEnumerable <T[]> Permutations <T>(T[] values)
        {
            int[] idx = Matrix.Indices(0, values.Length);

            int j, l;

            while (true)
            {
                for (j = values.Length - 2; j >= 0; j--)
                {
                    if (idx[j + 1] > idx[j])
                    {
                        break;
                    }
                }

                if (j == -1)
                {
                    yield break;
                }

                for (l = values.Length - 1; l > j; l--)
                {
                    if (idx[l] > idx[j])
                    {
                        break;
                    }
                }

                int temp = idx[j];
                idx[j] = idx[l];
                idx[l] = temp;

                for (int i = j + 1; i < idx.Length; i++)
                {
                    if (i > idx.Length - i + j)
                    {
                        break;
                    }
                    temp   = idx[i];
                    idx[i] = idx[idx.Length - i + j];
                    idx[idx.Length - i + j] = temp;
                }

                yield return(values.Submatrix(idx));
            }
        }
Пример #3
0
        /// <summary>
        ///   Sorts the elements of an entire one-dimensional array using the given comparison.
        /// </summary>
        ///
        public static void Sort <T>(this T[] values, out int[] order, bool stable = false, ComparerDirection direction = ComparerDirection.Ascending)
            where T : IComparable <T>
        {
            if (!stable)
            {
                order = Matrix.Indices(values.Length);
                if (direction == ComparerDirection.Ascending)
                {
                    Array.Sort(values, order);
                }
                else
                {
                    Array.Sort(values, order, new GeneralComparer <T>(direction));
                }

                return;
            }

            var keys = new KeyValuePair <int, T> [values.Length];

            for (var i = 0; i < values.Length; i++)
            {
                keys[i] = new KeyValuePair <int, T>(i, values[i]);
            }

            if (direction == ComparerDirection.Ascending)
            {
                Array.Sort(keys, values, new StableComparer <T>((a, b) => a.CompareTo(b)));
            }
            else
            {
                Array.Sort(keys, values, new StableComparer <T>((a, b) => - a.CompareTo(b)));
            }

            order = new int[values.Length];
            for (int i = 0; i < keys.Length; i++)
            {
                order[i] = keys[i].Key;
            }
        }