输入一组数字输出其所有的全排列

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Arrangenum
{
    /// <summary>
    /// 采用插值算法来求全排列,即先取出该组数字中的任意一个值,再把剩下的值依次往里面插,
    /// 取出所有可能的结果,即为所有可能的排列。
    /// </summary>

    class Method
    {
        public static int allnum(string[] str1)//计算所有全排列的个数
        {
            int a = 1;
            int b;
            for (b = 1; b < str1.Length;b++ )
            {
                a=a*(b+1);
            }
            return a;
        }

        public static void arrstr(string[] str2, string[] str1)
        {
            int i;
            int p;
            string[] result = null;
            for (i = 0; i < str2.Length; i++)
            {
                string[] str3 = str2[i].Split(' ');
                int q = str3.Length + 1;//使新建数组的长度比传入的数组长度大1,以便后面向数组中插入数字
                p = q * str2.Length;
                string[] str4 = new string[q];//在内存堆上new出两个数组,
                string[] str5 = new string[q];//而不是一个为数组的两个引用
                int s;
                for (s = 0; s < str3.Length; s++)
                {
                    str4[s] = str3[s];//对两个数组赋相同的值
                    str5[s] = str3[s];
                }
                int t;
                string[] str6 = new string[q];
                for (t = 0; t < q; t++)
                {
                    str4 = movstr(str4, str1, t, q);//调用movstr方法向str4中插入数字
                    string st1 = "";
                    int n;
                    for (n = 0; n < str4.Length; n++)
                    {
                        st1 = st1 + str4[n] + " ";//把插入后的结果转化为字符串,中间用空格隔开
                    }
                    st1 = st1.Substring(0, st1.Length - 1);
                    str6[t] = st1;
                    str4 = copystr(str5);//调用copystr方法把数组str4还原
                }
                string[] check = str6[0].Split(' ');
                if (check.Length < str1.Length)          //判断排列后的数组长度是否等于要排列的数组的长度,是的话则证明排列完成, 
                {
                    arrstr(str6, str1);                          //不是的话则使用递归调用继续往里面插入数字,直至它们长度相等
                }
                else
                {
                    result = str6;
                    int y;
                    for (y = 0; y < result.Length; y++)
                    {
                        Console.WriteLine(result[y]);
                    }
                }
            }
        }

        static string[] movstr(string[] str4, string[] str1, int t, int q)
        {
            if (t == (q - 1))                              //向数组中插入数字,如果要插入的位置是数组的最后一位的话则直接对其最后一位
            {
                str4[t] = str1[q - 1];                 //赋值,如果不是的话,则从要插入的位置起,把所有的元素都向后移一位,然后再
            }
            else                                              //把数字插入要插入的位置,因为要插入的数组最后一位是空值,所以向后移一位时
            {
                int m;                                       //不会出现元素丢失
                for (m = (q - 1); m > t; m--)
                {
                    str4[m] = str4[m - 1];
                }
                str4[t] = str1[q - 1];
            }
            return str4;
        }

        static string[] copystr(string[] str5)        
        {
            int x;                                                                   //把字符数组还原为未插入数字之前的排列,

            string[] str7 = new string[str5.Length];             // 采用先把另一个相等的数组先转化为字符串, 
            string st2 = "";                                                   //再把字符串转化为数组并赋给原数组的方式,

            for (x = 0; x < str5.Length; x++)                       //是因为数组引用的是内存堆中的地址,直
            {                                                                       //接赋值的话,只是把引用的地址传了过去,

                st2 = st2 + str5[x] + " ";                              //这样两个数组引用了相同的地址,循环后再
            }                                                                      //次赋值的话就会出现错误的结果
            st2 = st2.Substring(0, st2.Length - 1);
            str7 = st2.Split(' ');
            return str7;
        }

    }

    class Program
    {
        static void Main()
        {
            try
            {
                Console.WriteLine("请输入要排序的数字,中间用逗号隔开,并按回车确认:");
                string st = Console.ReadLine();
                string[] rst = st.Split(',');
                int c;
                int[] num = new int[rst.Length];        //增加一个数字数组,
                for (c = 0; c < rst.Length; c++)
                {
                    num[c] = Convert.ToInt16(rst[c]);   //并把字符数组转换为数字数组,
                }
                string[] str = new string[num.Length];
                for (c = 0; c < num.Length; c++)        //然后再转换为字符数组,是为了当在输入的不是数字时抛出异常
                {
                    str[c] = Convert.ToString(num[c]);
                }
                string[] str1 = str;
                string[] str2 = { str1[0] };
                int a;
                a = Method.allnum(str1);
                Console.WriteLine("全排列的个数为{0}个,结果为:",a);
                Method.arrstr(str2, str1); 
            }
            catch(Exception e)//捕捉异常,并输出
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

你可能感兴趣的:(输入一组数字输出其所有的全排列)