排列组合算法封装2

1.指定字符数组,从中抽取m个,组合,不重复

使用方法:

string str = "1234";
//字符数组中抽取2个进行组合
Extract extract = new Extract(str, 2);
extract.OnCreateOneGroup += (e) =>
{
    Console.WriteLine(e);
};
extract.DoExtract();

//字符数组中从1到当前数组个数的所有可能组合
Extract extract = new Extract();
extract.OnCreateOneGroup += (e) =>
{
    Console.WriteLine(e);
};
for (int i = 0; i < str.Length; i++)
{
    extract.DoExtract(str, i + 1);
}



类封装:

/// <summary>
/// 从指定 字符数组中 抽取指定个数的组合
/// 抽取结果组合,不重复,和排序无关
/// </summary>
public class Extract
{
    /// <summary>
    /// 当前需要排列着的数组
    /// </summary>
    private char[] _Source = null;
    /// <summary>
    /// 从数组中获取的个数
    /// </summary>
    private int _Count = 0;
    /// <summary>
    /// 当创建一个组合成功时,执行
    /// </summary>
    public Action<string> OnCreateOneGroup;
    /// <summary>
    /// 初始化
    /// </summary>
    public Extract() { }
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="Source">指定原数组</param>
    /// <param name="Count">抽取个数</param>
    public Extract(char[] Source, int Count)
    {
        this._Source = Source;
        _Count = Count;
    }
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="Source">字符串</param>
    /// <param name="Count">抽取个数</param>
    public Extract(string Source, int Count)
    {
        this._Source = Source.ToArray();
        this._Count = Count;
    }
    /// <summary>
    /// 执行排列
    /// </summary>
    public void DoExtract()
    {
        DoExtract(_Source, _Count);
    }
    /// <summary>
    /// 执行排列
    /// </summary>
    /// <param name="source">源字符数组</param>
    /// <param name="count">排列的个数</param>
    public void DoExtract(char[] source, int count)
    {
        int[] result = new int[count];
        int sourceCount = source.Length;
        combine(source, sourceCount, count, result, count);
    }
    /// <summary>
    /// 执行排列
    /// </summary>
    /// <param name="source">源字符串</param>
    /// <param name="count">抽取个数</param>
    public void DoExtract(string source, int count)
    {
        DoExtract(source.ToArray(), count);
    }
    /// <summary>
    /// 获取的子集合 出现的所有项不会重复,跟子集合的排列顺序没有关系
    /// </summary>
    private void combine(char[] a, int n, int m, int[] b, int M)
    {
        for (int i = n; i >= m; i--)//注意这里的循环范围
        {
            b[m - 1] = i - 1;
            if (m > 1)
                combine(a, i - 1, m - 1, b, M);
            else
            {
                StringBuilder builder = new StringBuilder(100);
                for (int j = M - 1; j >= 0; j--)
                {
                    char item = a[b[j]];
                    builder.Append(item);
                }
                //创建一组完成
                if (OnCreateOneGroup != null)
                {
                    OnCreateOneGroup(builder.ToString());
                }
            }
        }
    }
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值