A general solution to the problem of N-bit number ordering

Source: Internet
Author: User
Tags foreach continue final sort

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));


    }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.