/// <summary> /// Common intializer used by the multiple flavors of constructors. /// </summary> /// <remarks> /// Copies information provided and then creates a parellel int array of lexicographic /// orders that will be used for the actual permutation algorithm. /// The input array is first sorted as required for WithoutRepetition and always just for consistency. /// This array is constructed one of two way depending on the type of the collection. /// /// When type is MetaCollectionType.WithRepetition, then all N! permutations are returned /// and the lexicographic orders are simply generated as 1, 2, ... N. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 2 3 4 5 6 7} /// /// When type is MetaCollectionType.WithoutRepetition, then fewer are generated, with each /// identical element in the input array not repeated. The lexicographic sort algorithm /// handles this natively as long as the repetition is repeated. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 1 2 3 4 5 5} /// </remarks> private void Initialize(IList<T> values, GenerateOption type, IComparer<T> comparer) { myMetaCollectionType = type; myValues = new List<T>(values.Count); myValues.AddRange(values); myLexicographicOrders = new int[values.Count]; if(type == GenerateOption.WithRepetition) { for(int i = 0; i < myLexicographicOrders.Length; ++i) { myLexicographicOrders[i] = i; } } else { if(comparer == null) { comparer = new SelfComparer<T>(); } myValues.Sort(comparer); int j = 1; if(myLexicographicOrders.Length > 0) { myLexicographicOrders[0] = j; } for(int i = 1; i < myLexicographicOrders.Length; ++i) { if(comparer.Compare(myValues[i - 1], myValues[i]) != 0) { ++j; } myLexicographicOrders[i] = j; } } myCount = GetCount(); }
/// <summary> /// Create a permutation set from the provided list of values. /// The values will be compared using the supplied IComparer. /// The repetition type defaults to MetaCollectionType.WithholdRepetitionSets /// </summary> /// <param name="values">List of values to permute.</param> /// <param name="type">The type of permutation set to calculate.</param> /// <param name="comparer">Comparer used for defining the lexigraphic order.</param> public Permutations(IList <T> values, GenerateOption type = GenerateOption.WithoutRepetition, IComparer <T>?comparer = null) { if (values == null) { throw new ArgumentNullException(nameof(values)); } /// Copies information provided and then creates a parellel int array of lexicographic /// orders that will be used for the actual permutation algorithm. /// The input array is first sorted as required for WithoutRepetition and always just for consistency. /// This array is constructed one of two way depending on the type of the collection. /// When type is MetaCollectionType.WithRepetition, then all N! permutations are returned /// and the lexicographic orders are simply generated as 1, 2, ... N. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 2 3 4 5 6 7} /// When type is MetaCollectionType.WithoutRepetition, then fewer are generated, with each /// identical element in the input array not repeated. The lexicographic sort algorithm /// handles this natively as long as the repetition is repeated. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 1 2 3 4 5 5} Type = type; myValues = new List <T>(values.Count); myValues.AddRange(values); myLexicographicOrders = new int[values.Count]; if (type == GenerateOption.WithRepetition) { for (var i = 0; i < myLexicographicOrders.Length; ++i) { myLexicographicOrders[i] = i; } } else { if (comparer == null) { comparer = new SelfComparer <T>(); } myValues.Sort(comparer); var j = 1; if (myLexicographicOrders.Length > 0) { myLexicographicOrders[0] = j; } for (var i = 1; i < myLexicographicOrders.Length; ++i) { if (comparer.Compare(myValues[i - 1], myValues[i]) != 0) { ++j; } myLexicographicOrders[i] = j; } } Count = GetCount(); }
private void Initialize(IList <T> values, GenerateOption type, IComparer <T> comparer) { _myMetaCollectionType = type; _myValues = new List <T>(values.Count); _myValues.AddRange(values); _myLexicographicOrders = new int[values.Count]; switch (type) { case GenerateOption.WithRepetition: { for (var i = 0; i < _myLexicographicOrders.Length; ++i) { _myLexicographicOrders[i] = i; } break; } default: { if (comparer == null) { comparer = new SelfComparer <T>(); } _myValues.Sort(comparer); var j = 1; if (_myLexicographicOrders.Length > 0) { _myLexicographicOrders[0] = j; } for (var i = 1; i < _myLexicographicOrders.Length; ++i) { if (comparer.Compare(_myValues[i - 1], _myValues[i]) != 0) { ++j; } _myLexicographicOrders[i] = j; } break; } } Count = GetCount(); }
/// <summary> /// Common intializer used by the multiple flavors of constructors. /// </summary> /// <remarks> /// Copies information provided and then creates a parellel int array of lexicographic /// orders that will be used for the actual permutation algorithm. /// The input array is first sorted as required for WithoutRepetition and always just for consistency. /// This array is constructed one of two way depending on the type of the collection. /// /// When type is MetaCollectionType.WithRepetition, then all N! permutations are returned /// and the lexicographic orders are simply generated as 1, 2, ... N. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 2 3 4 5 6 7} /// /// When type is MetaCollectionType.WithoutRepetition, then fewer are generated, with each /// identical element in the input array not repeated. The lexicographic sort algorithm /// handles this natively as long as the repetition is repeated. /// E.g. /// Input array: {A A B C D E E} /// Lexicograhpic Orders: {1 1 2 3 4 5 5} /// </remarks> private void Initialize(ICollection <T> values, GenerateOption type, IComparer <T> comparer) { Type = type; _values = new List <T>(values.Count); _values.AddRange(values); _lexicographicOrders = new Int32[values.Count]; if (type == GenerateOption.WithRepetition) { for (Int32 i = 0; i < _lexicographicOrders.Length; ++i) { _lexicographicOrders[i] = i; } } else { if (comparer == null) { comparer = new SelfComparer <T>(); } _values.Sort(comparer); Int32 j = 1; if (_lexicographicOrders.Length > 0) { _lexicographicOrders[0] = j; } for (Int32 i = 1; i < _lexicographicOrders.Length; ++i) { if (comparer.Compare(_values[i - 1], _values[i]) != 0) { ++j; } _lexicographicOrders[i] = j; } } Count = GetCount(); }
private void Initialize(IList <T> values, GenerateOption type, IComparer <T> comparer) { this.myMetaCollectionType = type; this.myValues = new List <T>(values.Count); this.myValues.AddRange(values); this.myLexicographicOrders = new int[values.Count]; if (type == GenerateOption.WithRepetition) { for (int i = 0; i < this.myLexicographicOrders.Length; i++) { this.myLexicographicOrders[i] = i; } } else { if (comparer == null) { comparer = new SelfComparer <T>(); } this.myValues.Sort(comparer); int num = 1; if (this.myLexicographicOrders.Length != 0) { this.myLexicographicOrders[0] = num; } for (int j = 1; j < this.myLexicographicOrders.Length; j++) { if (comparer.Compare(this.myValues[j - 1], this.myValues[j]) != 0) { num++; } this.myLexicographicOrders[j] = num; } } this.myCount = this.GetCount(); }