Two days ago saw this post: see the two interview questions, the second problem is very representative, so the intention to do a bit.
Algorithm title: An arbitrary three-digit (1000-bit is not the same), to the number of 1000 in different order of the total number of different three digits? What's the difference? (C #) Example: 123:123,132,213,231,312,321.
The idea is to write 3 loops to get the answer together, but if n digits how to write n loop? So immediately thought of using recursion to solve the problem. Take one number at a time and then take the first one from the rest of the numbers, and so on until you get the end of the last number. But there's a small problem with two results for 1, 123, 132, which needs to be saved with a list, but it's not that elegant. So I chose the favorite yield return to simplify the code.
The key to the recursive program is to find the endpoint, at first I tried a few of the final conditions are unsuccessful, and finally calm down to think about the process of sorting is the number of n is enumerated, so the final condition is the digit number. The last question in the province. There can be no duplication in the arrangement, as long as the simulation of the sequencing process is clear:
Start: Select the leftmost number 1, its string is labeled 0, and 1 numbers are currently enumerated
Recursion for the first time: start from the beginning, because the last round of the number labeled 0 has been taken, so use the number subscript 1, to determine whether the subscript 1 has been used, because it is not used, then continue recursion, the current enumeration of 2 numbers
Recursive second: Because the 3rd number is currently enumerated, it reaches the endpoint and returns 3.
In this sequence we need to record the subscript for each selected number, and then the next time we enumerate to see if it already exists, so I use an array of the same size as the number of digits to record the subscript of the number selected during each sort.
Okay, it doesn't even matter. Directly on the code, the code is the best document, but before I paste the specific code I want to introduce my two auxiliary functions:
view Plaincopy to Clipboardprint?
//Apply an operation to each of the traversed elements
public static void For<t> (this ienumerable<t> itor, action<t> proc)
{
foreach (T item in itor)
proc (item);
}
//Judge whether an element is in an array
public static bool Exist<t> (this t[] arr, func<t, bool> predicate)
{
for (int i = 0; i < arr. Length; ++i)
{
if (predicate (arr[i))
return true;
}
return false;
}
//ok, the core code is here:
public static ienumerable<string> Combin (string source)
{
int[] trace = new Int[source. Length];
for (int i = 0; i < source. Length; ++i)
{
foreach (String item in Combin (source, I, 1, trace))
{
yield return item;
}
}
}
///<summary>
///sort Recursive algorithm
///</summary>
///<param name= "source" > Digital </param>
///<param name= "cur" > Current subscript </param>
///<param name= "Deep" > Current number of enumerations </param>
///<param name= "Trace" > Trace, used to repeat </param>
///<returns> return sorted numbers </returns>
private static ienumerable<string> Combin (string source, int cur, int deep, int[] trace)
{
char tmp = source[cur]; Gets the current enumerated number
trace[deep-1] = cur; Put the current subscript into the trace
if (deep = = Source. Length)//Termination condition
yield return TMP. ToString ();
Else
{
for (int i = 0; i < source. Length; ++i)//enumeration
{
for (int j = Deep J < trace.) Length; ++J)//track clear 0
Trace[j] =-1; -1 representatives not recorded
if (cur = i | | trace. Exist (P =>//repetitive filtration
{
if (p = = 1) return false;
return p = = i;
}))
continue;
foreach (String tail in Combin (source, I, deep + 1, trace))
{
yield return tmp + tail;
}
}
}
}
//See the effect
public static void Main ()
{
Combin ("1234"). For (I => Console.WriteLine (i));
}
//Apply an operation to each of the traversed elements
public static void For<t> (this ienumerable<t> itor, action<t> proc)
{
foreach (T item in itor)
proc (item);
}
//Judge whether an element is in an array
public static bool Exist<t> (this t[] arr, func<t, bool> predicate)
{
for (int i = 0; i < arr. Length; ++i)
{
if (predicate (arr[i))
return true;
}
return false;
}
//ok, the core code is here:
public static ienumerable<string> Combin (string source)
{
int[] trace = new int [source. Length];
for (int i = 0; i < source. Length; ++i)
{
foreach (String item in Combin (source, I, 1, trace))
{
yield return item;
}
}
}
///<summary>
///sort Recursive algorithm
///</summary>
///<param name= "source" > Digital </param>
///<param name= "cur" > Current subscript </param>
///<param name= "Deep" > Current number of enumerations </param>
///<param name= "Trace" > Trace, used to repeat </param>
///<returns> return sorted numbers </returns>
private static ienumerable<string> Combin (string source, int cur, int deep, int[] trace)
{
char tmp = source[cur]; Gets the current enumerated number
trace[deep-1] = cur; Put the current subscript into the trace
if (deep = = Source. Length)//Termination condition
yield return TMP. ToString ();
Else
{
for (int i = 0; i < source. Length; ++i)//enumeration
{
for (int j = Deep J < trace.) Length; ++J)//track clear 0
Trace[j] =-1; -1 representatives not recorded
if (cur = i | | trace. Exist (P =>//repetitive filtration
{
if (p = = 1) return false;
return p = = i;
}))
Continue
foreach (String tail in Combin (source, I, deep + 1, trace))
{
yield return tmp + tail;
}
}
}
}
//See the effect
public static void Main ()
{
Combin ("1234"). For (I => Console.WriteLine (i));
}