C# 排列组合算法

/*
 * A Combination & Permutation Algorithm Implemented with C#
 * Nov. 25, 2006
 * by Adrian
 * E-mail(Windows Live Messenger): sanyuexx@hotmail.com
 * Blog: http://www.cnblogs.com/dah
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace AbsPos
{
    public class Combinations<T> : IEnumerable<IList<T>>
    {
        private List<IList<T>> _combinations;
        private IList<T> _items;
        private int _length;
        private int[] _endIndices;

        public Combinations(IList<T> itemList)
            : this(itemList, itemList.Count)
        {
        }

        public Combinations(IList<T> itemList, int length)
        {
            _items = itemList;
            _length = length;
            _combinations = new List<IList<T>>();
            _endIndices = new int[length];
            int j = length - 1;
            for (int i = _items.Count - 1; i > _items.Count - 1 - length; i--)
            {
                _endIndices[j] = i;
                j--;
            }
            ComputeCombination();
        }

        private void ComputeCombination()
        {
            int[] indices = new int[_length];
            for (int i = 0; i < _length; i++)
            {
                indices[i] = i;
            }

            do
            {
                T[] oneCom = new T[_length];
                for (int k = 0; k < _length; k++)
                {
                    oneCom[k] = _items[indices[k]];
                }
                _combinations.Add(oneCom);
            }
            while (GetNext(indices));
        }

        private bool GetNext(int[] indices)
        {
            bool hasMore = true;

            for (int j = _endIndices.Length - 1; j > -1; j--)
            {
                if (indices[j] < _endIndices[j])
                {
                    indices[j]++;
                    for (int k = 1; j + k < _endIndices.Length; k++)
                    {
                        indices[j + k] = indices[j] + k;
                    }
                    break;
                }
                else if (j == 0)
                {
                    hasMore = false;
                }
            }
            return hasMore;
        }

        public int Count
        {
            get { return _combinations.Count; }
        }

        public IEnumerator<IList<T>> GetEnumerator()
        {
            return _combinations.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (IEnumerator<IList<T>>)GetEnumerator();
        }
    }
}

 

 

/*
 * A Combination & Permutation Algorithm Implemented with C#
 * Nov. 25, 2006
 * by Adrian
 * E-mail(Windows Live Messenger): sanyuexx@hotmail.com
 * Blog: http://www.cnblogs.com/dah
 */
using System;
using System.Collections.Generic;
using System.Text;

namespace AbsPos
{
    public class Permutations<T> : IEnumerable<IList<T>>
    {
        private List<IList<T>> _permutations;
        private IList<T> _items;
        private int _length;
        private List<int[]> _indices;
        private int[] _value;
        private int _level = -1;

        public Permutations(IList<T> items)
            : this(items, items.Count)
        {
        }

        public Permutations(IList<T> items, int length)
        {
            _items = items;
            _length = length;
            _permutations = new List<IList<T>>();
            _indices = new List<int[]>();
            BuildIndices();
            foreach (IList<T> oneCom in new Combinations<T>(items, length))
            {
                _permutations.AddRange(GetPermutations(oneCom));
            }
        }

        private void BuildIndices()
        {
            _value = new int[_length];
            Visit(0);
        }

        private void Visit(int k)
        {
            _level += 1;
            _value[k] = _level;

            if (_level == _length)
            {
                _indices.Add(_value);
                int[] newValue = new int[_length];
                Array.Copy(_value, newValue, _length);
                _value = newValue;
            }
            else
            {
                for (int i = 0; i < _length; i++)
                {
                    if (_value[i] == 0)
                    {
                        Visit(i);
                    }
                }
            }

            _level -= 1;
            _value[k] = 0;
        }

        private IList<IList<T>> GetPermutations(IList<T> oneCom)
        {
            List<IList<T>> t = new List<IList<T>>();

            foreach (int[] idxs in _indices)
            {
                T[] onePerm = new T[_length];
                for (int i = 0; i < _length; i++)
                {
                    onePerm[i] = oneCom[idxs[i] - 1];
                }
                t.Add(onePerm);
            }

            return t;
        }

        private int GetFactorial(int n)
        {
            int result = 1;
            while (n > 1)
            {
                result *= n;
                n--;
            }
            return result;
        }

        public IEnumerator<IList<T>> GetEnumerator()
        {
            return _permutations.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (System.Collections.IEnumerator)_permutations.GetEnumerator();
        }

        public int Count
        {
            get
            {
                return _permutations.Count;
            }
        }
    }
}

 

 public Form1()
        {
            InitializeComponent();
            ShowCombinations<int>(new int[] { 1, 2, 3 }, 2);
        }
        void ShowCombinations<T>(T[] array, int length)
        {
            Combinations<T> combinations = new Combinations<T>(array, length);
            Console.WriteLine("{0} Combinations of Array /"{1}/":/n", combinations.Count, GetString<T>(array));
            foreach (IList<T> oneCom in combinations)
            {
                listBox1.Items.Add(GetString<T>(oneCom));
            }
        }
        string GetString<T>(IList<T> list)
        {
            StringBuilder sb = new StringBuilder();
            foreach (T item in list)
            {
                sb.Append(item.ToString() + ",");
            }
            sb.Remove(sb.Length - 1, 1);
            return sb.ToString();
        }

结果:12

         13

         23

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值