算法(全排列算法封装)

本算法是教材中的全排列方法之一,本人仅做封装,在此感谢发现算法和传播算法的大牛们.
    /// <summary>
    /// 全排列算法,算法原理:Perm(n)=[n]*Pern(n-1).N的全排列等于将N个数取一个放在第N个位置后,剩下的N-1个数做全排列。
    /// 这个算法的一个用途是进行行列式的展开和计算,这也是这次封装这个算法的目的。
    /// </summary>
    public class Permulation
    {
        /// <summary>
        /// 排列结果
        /// </summary>
        private List<List<int>> _PermArray { get; set; }
        /// <summary>
        /// 去重用.
        /// </summary>
        private Dictionary<string, List<int>> _NoRepeatArray { get; set; }
        /// <summary>
        /// 要排列的整数数组
        /// </summary>
        private int[] _Numbers { get; set; }
        /// <summary>
        /// 元素个数
        /// </summary>
        private int _N { get; set; }
        /// <summary>
        /// 是否去重.
        /// </summary>
        private bool _RemoveDup { get; set; }

        /// <summary>
        /// 全排列计数
        /// </summary>
        public int TotalCount { get; set; }
        /// <summary>
        /// 排列结果
        /// </summary>
        public List<List<int>> PermulationArray
        {
            get
            {
                return _PermArray;
            }
        }
        /// <summary>
        /// 任意给定数字数组进行全排列
        /// </summary>
        /// <param name="Numbers">数组</param>
        /// <param name="RemoveDup">是否去重</param>
        public Permulation(int[] Numbers, bool RemoveDup = false)
        {
            _NoRepeatArray = new Dictionary<string, List<int>>();
            _PermArray = new List<List<int>>();
            TotalCount = 0;
            _Numbers = Numbers;
            _N = Numbers.Count();
            _RemoveDup = RemoveDup;
        }
        /// <summary>
        /// 自然数1-N全排列
        /// </summary>
        /// <param name="N"></param>
        public Permulation(int N)
        {
            _PermArray = new List<List<int>>();
            TotalCount = 0;
            _Numbers = new int[N];
            for (int i = 1; i <= N; i++)
            {
                _Numbers[i - 1] = i;
            }
            _N = N;
        }
        /// <summary>
        /// 交换位置.
        /// </summary>
        /// <param name="Nums"></param>
        /// <param name="i"></param>
        /// <param name="j"></param>
        private void Swap(int[] Nums, int i, int j)
        {
            int theTemp = Nums[i - 1];
            Nums[i - 1] = Nums[j - 1];
            Nums[j - 1] = theTemp;

        }
        /// <summary>
        /// 执行全排列
        /// </summary>
        public void DoCalculation()
        {
            DoArray(1);
        }
        /// <summary>
        /// 递归算法进行全排列.
        /// </summary>
        /// <param name="NextIndex"></param>
        private void DoArray(int NextIndex)
        {
            if (NextIndex > _N)
            {
                var theNums = new List<int>();
                //利用字典本身的字符串哈希算法判重。
                var theSeqStr = "";
                for (int i = 0; i < _N; i++)
                {
                    //注意这里需要分割,防止1 23和12 3之类造成的重复.
                    theSeqStr += "," + _Numbers[i];
                    theNums.Add(_Numbers[i]);
                }
                if (_RemoveDup)
                {
                    if (!_NoRepeatArray.ContainsKey(theSeqStr))
                    {
                        _NoRepeatArray.Add(theSeqStr, theNums);
                        _PermArray.Add(theNums);
                        TotalCount++;
                    }
                }
                else
                {
                    _PermArray.Add(theNums);
                    TotalCount++;
                }

            }
            else
            {
                //与后面的所有位置进行交换,但注意,每次交换完,应复原。
                for (int i = NextIndex; i <= _N; i++)
                {
                    Swap(_Numbers, NextIndex, i);
                    DoArray(NextIndex + 1);
                    //复原
                    Swap(_Numbers, NextIndex, i);
                }
            }
        }

    }

注:本算法只经过简单测试,没经过大批量测试。

时间: 2024-07-30 08:44:13

算法(全排列算法封装)的相关文章

全排列算法 --javascript 实现

(function(){ var ret = new Array(); var A = function a(str){ if(str == undefined || str == null){return new Array();} if(str.length < 2) {return new Array(str);} if(str.length == 2) {return new Array(str[0]+str[1],str[1]+str[0]);} for(var k = 0;k <

全排列算法(转)

列出全排列的初始思想: 解决一个算法问题,我比较习惯于从基本的想法做起,我们先回顾一下我们自己是如何写一组数的全排列的:1,3,5,9(为了方便,下面我都用数进行全排列而不是字符). 1,3,5,9.(第一个) 首先保持第一个不变,对3,5,9进行全排列. 同样地,我们先保持3不变,对5,9进行全排列. 保持5不变,对9对进行全排列,由于9只有一个,它的排列只有一种:9.接下来5不能以5打头了,5,9相互交换,得到 1,3,9,5. 此时5,9的情况都写完了,不能以3打头了,得到 1,5,3,9

不会全排列算法(Javascript实现),我教你呀!

今天我很郁闷,在实验室凑合睡了一晚,准备白天大干一场,结果一整天就只做出了一道算法题.看来还是经验不足呀,同志仍需努力呀. 算法题目要求是这样的: Return the number of total permutations of the provided string that don't have repeated consecutive letters. Assume that all characters in the provided string are each unique.F

两种常用的全排列算法(java)

问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"."52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0.2都不行,5可以,将5和2交换得到"956

字符串非重复全排列算法

[题目描述] 输入一个字符串,打印出该字符串中字符的所有排列. 例如输入字符串abc,则输出由字符a.b.c 所能排列出来的所有字符串 abc.acb.bac.bca.cab 和 cba. [分析] 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列.以对字符串abc进行全排列为例,我们可以这么做:以abc为例 固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac 固定b,求后面ac的排列:bac,bca,求好

全排列算法的递归与非递归实现

全排列算法的递归与非递归实现 全排列算法是常见的算法,用于求一个序列的全排列,本文使用C语言分别用递归与非递归两种方法实现,可以接受元素各不相同的输入序列. 题目来自leetcode: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3

java全排列算法实现 --- 小例子实现

Question:猜算式 看下面的算式: □□ x □□ = □□ x □□□ 它表示:两个两位数相乘等于一个两位数乘以一个三位数. 如果没有限定条件,这样的例子很多. 但目前的限定是:这9个方块,表示1~9的9个数字,不包含0. 该算式中1至9的每个数字出现且只出现一次! 比如: 46 x 79 = 23 x 158 54 x 69 = 27 x 138 54 x 93 = 27 x 186 ..... 请编程,输出所有可能的情况! 注意: 左边的两个乘数交换算同一方案,不要重复输出! 不同方

【codeup】1959: 全排列 及全排列算法详解

题目描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存

全排列算法(字典序法、SJT Algorithm 、Heap&#39;s Algorithm)

一.字典序法 1) 从序列P的右端开始向左扫描,直至找到第一个比其右边数字小的数字,即. 2) 从右边找出所有比大的数中最小的数字,即. 3) 交换与. 4) 将右边的序列翻转,即可得到字典序的下一个排列. 5) 重复上面的步骤,直至得到字典序最大的排列,即左边数字比右边的大的降序排列. 二.SJT Algorithm 初始状态为. 1) 找到最大的可移动数m(当一个数指向一个比它小的数是,该数就是可移动数) 2) 交换m和m所指向的数 3) 改变所有比m大的数的方向 4) 重复上面的步骤,直至