How to reverse a string 2character and 2character from the end c# - c#

Sample string:
A3148579
Expected result:
798514A3
I tried this code:
public static string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
the actual result is 9758413A
but I want 798514A3
thanks everyone

You can try below code. This is just to give you a idea and you can update based on the test cases and requirement. Below code works fine for your input which you have mentioned. I have not considered if the length is odd. You can do your research and update logic which will help you to learn and know more.
string input = "A3148579";
Stack stack = new Stack();
int count = 0;
string output = "";
for (int i = 0; i < input.Length/2; i++)
{
stack.Push(input.Substring(count, 2));
count = count + 2;
}
while (stack.Count > 0)
{
output += stack.Pop().ToString();
}

You can split the initial string into chunks of size = 2 (e.g. with a help of Substring); note that ToCharArray() returns chars i.e. chunks of size = 1.
Let's generalize the solution: now we have size of chunks
Code:
using System.Linq;
...
public static string Reverse(string s, int size = 2) {
if (size < 1)
throw new ArgumentOutOfRangeException(nameof(size));
if (string.IsNullOrEmpty(s))
return s;
int n = s.Length / size + (s.Length % size == 0 ? 0 : 1);
return string.Concat(Enumerable
.Range(0, n)
.Select(i => i < n - 1 ? s.Substring(i * size, size) : s.Substring(i * size))
.Reverse());
}
Demo:
Console.Write(Reverse("A3148579"));
Outcome:
798514A3

C# Example: Split An Array into Multiple Smaller Arrays
Use Lambda expression to extends Array class to include a new method called Split:
public static class MyArrayExtensions
{
/// <summary>
/// Splits an array into several smaller arrays.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array to split.</param>
/// <param name="size">The size of the smaller arrays.</param>
/// <returns>An array containing smaller arrays.</returns>
public static IEnumerable<IEnumerable<T>> Split<T>(this T[] array, int size)
{
for (var i = 0; i < (float)array.Length / size; i++)
{
yield return array.Skip(i * size).Take(size);
}
}
}
Test the new array class method:
[TestMethod]
public void TestSplit2()
{
string str = "A3148579";
char[] array1 = new char[str.Length];
for (int i = 0; i < array1.Length; i++)
{
array1[i] = i;
}
// Split into smaller arrays of maximal 2 elements
IEnumerable<IEnumerable<int>> splited = array1.Split<int>(2);
int j = 0;
foreach (IEnumerable<int> s in splited){
j++;
}
log.InfoFormat("Splitted in to {0} smaller arrays.", j);
}
Finally you just need to reverse the resulted array(smaller).

Related

Getting number of possible anagrams from a generic string, need a fast solution

I am currently working on an assignment where I need to write a small program that will take a generic string and should output how many possible anagrams that could be generated from the string.
The string that is the input can be up to 100 chars long and could include both lowercase and uppercase, in this case both lowercase and uppercase are considered distinct. The output should only be how many possible combinations, so I don't need to output the actual anagrams.The maximum timelimit is 1 second per string.
I have tried a number of diffrent ways of doing this, but one conclusion is that this should be solvable using some type of mathemathical algorithm.
The latest code I have tried with is this:
static void Main(string[] args)
{
string line;
while ((line = Console.ReadLine()) != null)
{
var uniqueStringArr = removeDuplicates(line);
Console.WriteLine(countDistinctPermutations(new string(uniqueStringArr)));
}
}
private static char[] removeDuplicates(string line)
{
var list = line.ToList();
return list.Distinct().ToArray();
}
static int MAX_CHAR = 100;
// Utility function to find factorial of n.
static int factorial(int n)
{
int fact = 1;
for (int i = 2; i <= n; i++)
fact = fact * i;
return fact;
}
// Returns count of distinct permutations
// of str.
static int countDistinctPermutations(String str)
{
int length = str.Length;
int[] freq = new int[MAX_CHAR];
// finding frequency of all the lower case
// alphabet and storing them in array of
// integer
for (int i = 0; i < length; i++)
if (str[i] >= 'a')
freq[str[i] - 'a']++;
// finding factorial of number of appearances
// and multiplying them since they are
// repeating alphabets
int fact = 1;
for (int i = 0; i < MAX_CHAR; i++)
fact = fact * factorial(freq[i]);
// finding factorial of size of string and
// dividing it by factorial found after
// multiplying
return factorial(length) / fact;
}
The thing is that this code does not give the correct answer for all my testcases.
The following sample data was provided for me :
Input string | Number of possible anagrams
at | 2
ordeals | 5040
abcdefghijklmnopqrstuvwxyz | 403291461126605635584000000
abcdefghijklmabcdefghijklm | 49229914688306352000000
abcdABCDabcd | 29937600
My code fixes the first two examples, but I get completly diffrent numbers for the other 3.
Is there anyone who can help me with this problem because I am running out of ideas ?
/Andreas
static BigInteger Factorial(long x)
{
return x <= 1 ? 1 : x * Factorial(x-1);
}
private static BigInteger NumberOfDistinctPermutationOf(string str)
{
BigInteger dividend = Factorial(str.Length);
foreach (char chr in str)
{
dividend /= Factorial(str.Count(c => c == chr));
str = str.Replace(chr.ToString(), string.Empty);
}
return dividend;
}
Description:
BigInteger Struct: Represents an arbitrarily large signed integer.
Enumerable.Count Method: Returns a number that represents how many elements in the specified sequence satisfy a condition.
String.Replace(String, String) Method: Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string.
GetNumberOfDistinctPermutation Method: Divides factorial of the length of the string by factorial of the number of occurrences of the char and then removes all occurrences of the char, for each char in the string.
static void Main(string[] args)
{
string line;
while ((line = Console.ReadLine()) != null)
{
Console.WriteLine($"{line} -> {countDistinctPermutations(line)}");
}
}
static BigInteger factorial(int n)
{
double fact = 1;
for (int i = 2; i <= n; i++)
fact = fact * i;
return fact;
}
static BigInteger countDistinctPermutations(String str)
{
// get a collection of {letter,occurences}
var duplicates = Array.GroupBy(p => p).Select(x => new { x.Key, count = x.Count() }).Where(x => x.count > 1);
BigInteger result = factorial(str.Length);
// foreach letter where occurence > 1 divide total permutations by the permutations for the occurence value (occurrence!)
foreach (var d in duplicates)
{
result /= factorial(d.count);
}
return result;
}
I only write code for a week so it's not that pretty but it works 100%.
static void Main(string[] args)
{
string inputData = Console.ReadLine();
Console.WriteLine(Solution(inputData));
}
static char[] convert(string text) // converting string to char[]
{
char[] newString = new char[text.Length];
for (int i = 0; i < text.Length; i++)
{
newString[i] = text[i];
}
return newString;
}
static double CalculateFctorial(double number) // calc. factorial
{
double factorial = 1;
for (int i = 1; i <= number; i++)
factorial *= i;
return factorial;
}
static int CountOcc(string text, char zet) // counting occurrences
{
int count = 0;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == zet)
{
count++;
}
}
return count;
}
static double Solution(string text) // the soluton, counting occurences of
// each char in string and each factorial
{
double net = 0;
double sol = 1;
char[] newText = convert(text);
for (int i = 0; i <= newText.Length; i++)
{
if (text.Length > 0)
{
net = CountOcc(text, newText[i]);
sol = sol * CalculateFctorial(net);
if (newText[i] == text[0])
{ text = text.Trim(text[0]); }
}
}
double solution = CalculateFctorial(newText.Length) / sol;
return solution;
}

C# Permutate a set of strings given n and given the maximum array length

How can you permutate the set of strings based on the set length, I have lets say 50 values in an array and only want to combine 24 values that is comma delimited Examples: (string1,string2,string3) but without ever repeating the combinations and the order. I have this code below.
class Program
{
static void Main(string[] args)
{
//var values1 = new[] { 1, 2, 3, 4, 5 };
//foreach (var permutation in values1.GetPermutations())
//{
// Console.WriteLine(string.Join(", ", permutation));
//}
var values2 = new[] { "asd", "das", "sad", "q1we", "asd" };
foreach (var permutation in values2.GetPermutations())
{
Console.WriteLine(string.Join(",", permutation));
}
Console.ReadLine();
}
}
public static class SomeExtensions
{
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> enumerable)
{
var array = enumerable as T[] ?? enumerable.ToArray();
var factorials = Enumerable.Range(0, array.Length + 1)
.Select(Factorial)
.ToArray();
for (var i = 0L; i < factorials[array.Length]; i++)
{
var sequence = GenerateSequence(i, array.Length - 1, factorials);
yield return GeneratePermutation(array, sequence);
}
}
private static IEnumerable<T> GeneratePermutation<T>(T[] array, IReadOnlyList<int> sequence)
{
var clone = (T[])array.Clone();
for (int i = 0; i < clone.Length - 1; i++)
{
Swap(ref clone[i], ref clone[i + sequence[i]]);
}
return clone;
}
private static int[] GenerateSequence(long number, int size, IReadOnlyList<long> factorials)
{
var sequence = new int[size];
for (var j = 0; j < sequence.Length; j++)
{
var facto = factorials[sequence.Length - j];
sequence[j] = (int)(number / facto);
number = (int)(number % facto);
}
return sequence;
}
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
private static long Factorial(int n)
{
long result = n;
for (int i = 1; i < n; i++)
{
result = result * i;
}
return result;
}
}
How can I be able to combine an array of string (24 values) into 100 rows of unique combination? Can you please explain how and whats the best way on how to do it?
I think that I would do it like this
public static class StringPermutator
{
/// <summary>
/// Class to permutate input values
/// </summary>
/// <param name="inputValues">An array of inputs to be permutated</param>
/// <param name="numberOfResults">The number of outputs we want to have</param>
/// <param name="maxValuesPerRow">The number of values to be combined in each output row</param>
/// <returns>An IEnumerable of unique permutated string ouptuts</returns>
public static IEnumerable<string> Permutate<T>(T[] inputValues, int numberOfResults, int maxValuesPerRow)
{
HashSet<string> output = new HashSet<string>();
Random rnd = new Random();
//Loop until we have the number of results we want
while (output.Count < numberOfResults)
{
StringBuilder sb = new StringBuilder();
HashSet<int> usedIndexes = new HashSet<int>();
//Loop until we have the right number of values in a single row
while (usedIndexes.Count < maxValuesPerRow)
{
int index = rnd.Next(inputValues.Length);
//Ensure that each index we use is unique and only used once per row
if (usedIndexes.Add(index))
sb.Append(inputValues[index].ToString()).Append(",");
}
sb.Length--; //remove the last comma
output.Add(sb.ToString()); //value is only added if unique
}
return output.ToList();
}
}
You can call it like this
var result = StringPermutator.Permutate(stringValues, 100, 24);
foreach (var permutation in result)
{
Console.WriteLine(string.Join(",", permutation));
}
Basically the class uses HashSet which ensures that only unique values can be entered, therefore we can be sure that our output is not duplicated and we just loop until we have the right number of generated output values.
Within this loop then we randomly pick an index to use, and to ensure that this is also unique for each output value then we again use a HashSet to store the indexes used and loop until we have combined the right number of values into a single output row.
The return is an Enumerable list.
This should work on any type of input value, not just strings.
Edit:
Just to clarify, as per the comments.
If you don't have enough inputs to generate the number of permutations and rows combinations that you need then you could get stuck in a loop. So you should code a method to break out of this but in order to keep the example simple I didn't do that.
I propose the use of more deterministic permutation generator. Couple this with existing LINQ extension methods like Select(), Distinct() and Take() and you've got what you need:
var results = values2.Permutations(24)
.Select(p => String.Join(",", p))
.Distinct()
.Take(100);
foreach (var permutation in results)
Console.WriteLine(permutation);
where Permutations() is implemented as an extension method. The number 24 here indicates how many items should be in each permutation. It is the k in nPk.
The Select() call creates a string string with all the items for the particular permutation.
The Distinct() call makes sure that we only end up with unique strings.
The Take() call limits the number of strings that we collect.
Here is a naive implementation using recursion to generate the permutations:
public static IEnumerable<T[]> Permutations<T>(this IEnumerable<T> source, int k)
{
if (k < 0)
throw new ArgumentOutOfRangeException(nameof(k), "May not be negative");
var items = source.ToArray();
if (k > items.Length)
throw new ArgumentOutOfRangeException(nameof(k), "May not be bigger than the number of items in source");
var buffer = new ArraySegment<T>(items, 0, k);
return Permute(0);
IEnumerable<T[]> Permute(int depth)
{
if (depth == k)
{
yield return buffer.ToArray();
yield break;
}
for (int i = depth; i < items.Length; i++)
{
Swap(depth, i);
foreach (var permutation in Permute(depth + 1))
yield return permutation;
Swap(depth, i);
}
}
void Swap(int a, int b)
{
if (a != b)
{
T t = items[a];
items[a] = items[b];
items[b] = t;
}
}
}
I leave it to you to replace the implementation with the algorithm of your choice.

C# Splitting a string [duplicate]

This question already has answers here:
Splitting a string into chunks of a certain size
(39 answers)
Closed 8 years ago.
I've got a problem. I have a string "3d8sAdTd6c" And I would need it to split it, so the conclusion would be:
3d
8s
Ad
Td
6c
If you could tell me how to do this I would be very grateful.
Perhaps:
string[] result = str
.Select((c, index ) => new{ c, index })
.GroupBy(x => x.index / 2)
.Select(xg => string.Join("", xg.Select(x => x.c)))
.ToArray();
This groups every second character and uses string.Join to concat them to a string.
Something like below should work with loops.
string str = "3d8sAdTd6c";
string newstr = "";
int size = 2;
int stringLength = str.Length;
for (int i = 0; i < stringLength ; i += size)
{
if (i + size > stringLength) size = stringLength - i;
newstr = newstr + str.Substring(i, size) + "\r\n";
}
Console.WriteLine(newstr);
string input = "3d8sAdTd6c";
for (int i = 0; i < input.Length; i+=2) {
Console.WriteLine(input.Substring(i,2));
}
To split any string into pairs of two characters:
/// <summary>
/// Split a string into pairs of two characters.
/// </summary>
/// <param name="str">The string to split.</param>
/// <returns>An enumerable sequence of pairs of characters.</returns>
/// <remarks>
/// When the length of the string is not a multiple of two,
/// the final character is returned on its own.
/// </remarks>
public static IEnumerable<string> SplitIntoPairs(string str)
{
if (str == null) throw new ArgumentNullException("str");
int i = 0;
for (; i + 1 < str.Length; i += 2)
{
yield return str.Substring(i, 2);
}
if (i < str.Length)
yield return str.Substring(str.Length - 1);
}
Usage:
var pairs = SplitIntoPairs("3d8sAdTd6c");
Result:
3d
8s
Ad
Td
6c

Get index of nth occurrence of char in a string

I'm trying to make a function that returns the index of the Nth occurrence of a given char in a string.
Here is my attempt:
private int IndexOfNth(string str, char c, int n)
{
int index = str.IndexOf(c) + 1;
if (index >= 0)
{
string temp = str.Substring(index, str.Length - index);
for (int j = 1; j < n; j++)
{
index = temp.IndexOf(c) + 1;
if (index < 0)
{
return -1;
}
temp = temp.Substring(index, temp.Length - index);
}
index = index + (str.Length);
}
return index;
}
This should find the first occurrence, chop off that front part of the string, find the first occurrence from the new substring, and on and on until it gets the index of the nth occurrence. However I failed to consider how the index of the final substring is going to be offset from the original actual index in the original string. How do I make this work?
Also as a side question, if I want the char to be the tab character do I pass this function '\t' or what?
Don't do that; IndexOf takes a second parameter that specifies where to start.
private static int IndexOfNth(string str, char c, int n) {
int s = -1;
for (int i = 0; i < n; i++) {
s = str.IndexOf(c, s + 1);
if (s == -1) break;
}
return s;
}
Taking all these substrings seems pretty wasteful to me. Why not just loop yourself?
private int IndexOfNth(string str, char c, int n)
{
int remaining = n;
for (int i = 0; i < str.Length; i++)
{
if (str[i] == c)
{
remaining--;
if (remaining == 0)
{
return i;
}
}
}
return -1;
}
(I considered using IndexOf in a loop like minitech's solution, but decided it was a bit fiddly. Either's fine, of course. Both basically do the same work, only ever checking each character once. Using IndexOf may be slightly more efficient, but go for whichever you find more readable.)
Using LINQ to find the index of the 5'th a in the string aababaababa:
var str = "aababaababa";
var ch = 'a';
var n = 5;
var result = str
.Select((c, i) => new { c, i })
.Where(x => x.c == ch)
.Skip(n - 1)
.FirstOrDefault();
return result != null ? result.i : -1;
I tend to first think about how to access the collection using Linq.
// 0-based n.
char result = str
.Where(x => x == c)
.Skip(n)
.FirstOrDefault();
Then I'll unpack the linq and add the indexed iteration.
int foundCount = -1;
for(int position = 0; position < str.Length; position++)
{
char x = str[position];
if (x == c)
{
foundCount += 1;
// 0-based n
if (foundCount == n)
{
return position;
}
}
}
return -1;
Then I think about: what if this method returned all the indexes so I can query them:
public IEnumerable<int> IndexesOf(string str, char c)
{
for(int position = 0; position < str.Length; position++)
{
char x = str[position];
if (x == c)
{
yield return position;
}
}
}
Called by:
int position = IndexesOf(str, c)
.Skip(n) // 0-based n
.DefaultIfEmpty(-1)
.First();
Instead of creating a bunch of substrings, why not use the IndexOf overload that takes a starting index? This will be both easier (you won't have to adjust the final index) and more efficient (you don't have to allocate a bunch of substrings).
Not tested but something like this should work:
private int IndexOfNth(string str, char c, int n)
{
int index = -1;
while (n-- > 0)
{
index = str.IndexOf(c, index + 1);
if (index == -1) break;
}
return index;
}
Hadn't seen anyone use the CharEnumerator yet...
public Int32 getNthIndex(string str, char c, Int32 n)
{
Int32 index = 0;
Int32 count = 0;
if (str != null && str.Length > 0 && !(n < 1))
{
CharEnumerator scanner = str.GetEnumerator();
while (scanner.MoveNext())
{
if (scanner.Current == c) { count++; }
if (count == n) { break; }
index++;
}
if (count < n) { index = -1; }
}
if (count == 0) { return -1; } else { return index; }
}
Should be pretty efficient, no substrings or anything, just scan through the string you're given and keep count.
You could use the following method which will return the nth occurrence of the specified character within the designated string.
public static int IndexOfNthCharacter(string str, int n, char c) {
int index = -1;
if (!str.Contains(c.ToString()) || (str.Split(c).Length-1 < n)) {
return -1;
}
else {
for (int i = 0; i < str.Length; i++) {
if (n > 0) {
index++;
}
else {
return index;
}
if (str[i] == c) {
n--;
}
}
return index;
}
}
Note that if the character you are searching for does not exist within the string you are searching or the the occurrence number you are searching for is greater than what exists in the string then this method will return -1.
First of all, I'd make it an extension method. This way, you can skip the otherwise obligatory null check and also just call it on a string like you would do with IndexOf, IndexOfAny etc.
Then I'd make two methods of this. One to retrieve all indexes (IndexesOf, that might come handy at sometime) and the other one (IndexOfNth) uses the first function to check for the nth index:
using System;
using System.Collections.Generic; // # Necessary for IList<int>
using System.Linq; // # Necessary for IList<int>.ToArray()
/// <summary>
/// Returns all indexes of the specified <paramref name="value"/> in the current string.
/// </summary>
/// <param name="#this">The current string this method is operating on.</param>
/// <param name="value">The value to be searched.</param>
/// <returns><c>Null</c>, if <paramref name="value"/> is <c>null</c> or empty.
/// An array holding all indexes of <paramref name="value"/> in this string,
/// else.</returns>
static int[] IndexesOf(this string #this, string value)
{
// # Can't search for null or string.Empty, you can return what
// suits you best
if (string.IsNullOrEmpty(value))
return null;
// # Using a list instead of an array saves us statements to resize the
// array by ourselves
IList<int> indexes = new List<int>();
int startIndex = 0;
while (startIndex < #this.Length)
{
startIndex = #this.IndexOf(value, startIndex);
if (startIndex >= 0)
{
// # Add the found index to the result and increment it by length of value
// afterwards to keep searching AFTER the current position
indexes.Add(startIndex);
startIndex += value.Length;
}
else
{
// # Exit loop, if value does not occur in the remaining string
break;
}
}
// # Return an array to conform with other string operations.
return indexes.ToArray();
}
/// <summary>
/// Returns the indexes of the <paramref name="n"/>th occurrence of the specified
/// <paramref name="value"/> in the current string.
/// </summary>
/// <param name="#this">The current string this method is operating on.</param>
/// <param name="value">The value to be searched.</param>
/// <param name="n">The 1-based nth occurrence.</param>
/// <returns><c>-1</c>, if <paramref name="value"/> is <c>null</c> or empty -or-
/// <paramref name="n"/> is less than 1.</returns>
static int IndexOfNth(this string #this, string value, int n /* n is 1-based */)
{
// # You could throw an ArgumentException as well, if n is less than 1
if (string.IsNullOrEmpty(value) || n < 1)
return -1;
int[] indexes = #this.IndexesOf(value);
// # If there are n or more occurrences of 'value' in '#this'
// return the nth index.
if (indexes != null && indexes.Length >= n)
{
return indexes[n - 1];
}
return -1;
}
You can overload these using char value instead of string value in the signature and calling their respective counterparts passing value.ToString(). Et voilá!
Surely, these methods can be refactored, e.g. using LINQ, make IndexesOf recursive etc.

Find string permutation including the single character using C# or F#

I would like to generate a list of all possible permutations of a string containing a variable list of characters.
For example if I have the string "ABC", I would like to have a list that contains all the possible variations, like: A, B, C, AB, BC.
Thank you.
It's hard to tell exactly what you want, but based on your example output here's how to do what I think you're after in F#.
let combinations (s:string) =
let rec loop acc i =
seq {
for i in i .. (s.Length - 1) do
let acc = acc + s.[i..i]
yield acc
yield! loop acc (i + 1)
}
loop "" 0
combinations "ABC" |> Seq.toList //["A"; "AB"; "ABC"; "AC"; "B"; "BC"; "C"]
Here's a LINQ version:
Func<string, IEnumerable<string>> perm = t =>
{
Func<string, string, IEnumerable<string>> perm2 = null;
perm2 =
(t0, t1s) =>
from n in Enumerable.Range(0, t1s.Length)
let c = t1s.Substring(n, 1)
let x = t1s.Remove(n, 1)
let h = t0 + c
from r in (new [] { h, }).Concat(perm2(h, x))
select r;
return perm2("", t);
};
Use it like this:
var ps = perm("abc");
And it will perform a lazy computation.
var ps = perm("abcdefghijklmnopqrstuvwxyz").Take(2);
// Only computes two values when executed
Here will return all of the permutations (not distinct) given a string of chars. it's not fast or efficient, but it does work...
public List<string> permute(string value, string prefix = "")
{
List<string> result = new List<string>();
for (int x=0;x<value.Length;x++)
{
result.Add(prefix + value[x]);
result.AddRange(permute( value.Remove(x, 1), prefix + value[x]));
}
return result;
}
To use:
List<string> output = permute("abc");
Check out this snippet at F# Snippets
If you are looking for a permutation by index (instead of having to iterate over all the permutations) you can use a numbering system called factoradics (Source) to find them. Here is the code from the original article, with a stronger C# style (the original code is very 'C++ish') and generics.
/// <summary>
/// Permutes the specified atoms; in lexicographical order.
/// </summary>
/// <typeparam name="T">The type of elements.</typeparam>
/// <param name="atoms">The atoms.</param>
/// <param name="index">The index of the permutation to find.</param>
/// <returns>The permutation.</returns>
public static IList<T> Permute<T>(this IList<T> atoms, int index)
{
var result = new T[atoms.Count];
Permute(atoms, result, index);
return result;
}
/// <summary>
/// Permutes the specified atoms; in lexicographical order.
/// </summary>
/// <typeparam name="T">The type of elements.</typeparam>
/// <param name="atoms">The atoms.</param>
/// <param name="target">The array to place the permutation in.</param>
/// <param name="index">The index of the permutation to find.</param>
public static void Permute<T>(this IList<T> atoms, IList<T> target, int index)
{
if (atoms == null)
throw new ArgumentNullException("atoms");
if (target == null)
throw new ArgumentNullException("target");
if (target.Count < atoms.Count)
throw new ArgumentOutOfRangeException("target");
if (index < 0)
throw new ArgumentOutOfRangeException("index");
var order = atoms.Count;
// Step #1 - Find factoradic of k
var perm = new int[order];
for (var j = 1; j <= order; j++)
{
perm[order - j] = index % j;
index /= j;
}
// Step #2 - Convert factoradic[] to numeric permuatation in perm[]
var temp = new int[order];
for (var i = 0; i < order; i++)
{
temp[i] = perm[i] + 1;
perm[i] = 0;
}
perm[order - 1] = 1; // right-most value is set to 1.
for (var i = order - 2; i >= 0; i--)
{
perm[i] = temp[i];
for (var j = i + 1; j < order; j++)
{
if (perm[j] >= perm[i])
perm[j]++;
}
}
// Step #3 - map numeric permutation to string permutation
for (var i = 0; i < order; ++i)
{
target[i] = atoms[perm[i] - 1];
}
}

Categories

Resources