01,02,03,04,05,06,07,08,09,10,    10个数字按2*2*2的模式,比如:01,02|03,04|05,06,总共83160种组合List<string> str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
            List<string> w = new List<string>();
            List<string> q = new List<string>();
            List<string> b = new List<string>();
            List<string> grp = new List<string>();
            List<string> tmp;            for (int m1 = 0; m1 < str.Count; m1++)
            {
                for (int m2 = m1 + 1; m2 < str.Count; m2++)
                {
                    w.Add(str[m1] + "," + str[m2]);
                }
            }
            for (int i = 0; i < w.Count; i++)
            {
                tmp = new List<string>();
                for (int n = 0; n < w[i].Length; n += 3)
                {
                    tmp.Add(w[i].Substring(n, 2));
                }
                for (int n = 0; n < tmp.Count; n++)
                {
                    str.Remove(tmp[n]);
                }
                for (int m1 = 0; m1 < str.Count; m1++)
                {
                    for (int m2 = m1 + 1; m2 < str.Count; m2++)
                    {
                        q.Add(str[m1] + "," + str[m2]);
                    }
                }
                str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" };
            }
            int k = 0;
            for (int m = 0; m < q.Count; m += 45)
            {
                for (int n = m; n <= m + 44; n++)
                {
                    grp.Add(w[k] + "|" + q[n]);
                }
                k++;
            }
            w.Clear();
            q.Clear();
我现在只弄出 01,02|03,04 第三段,我觉得好复杂,有简单些的算法吗?  

解决方案 »

  1.   


    版主大大,就不纠结是10还是12了嘛,三段 两两组合,有没有简单点的算法呀,谢谢。写第三段,我写得有些头痛,help
      

  2.   

    只能给你找出1万9千种排列。你看看是不是你的鸡国有次序颠倒的情况?using System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
                var cnt = 0;
                foreach (var r in N段两两组合(str, 3))
                {
                    Console.WriteLine($"第{++cnt}种组合:");
                    foreach (var d in r)
                        Console.Write($" {string.Join("|", d)} ");
                    Console.WriteLine();
                }
                Console.WriteLine("..............按任意键结束");
                Console.ReadKey();
            }        static IEnumerable<IEnumerable<IEnumerable<string>>> N段两两组合(IEnumerable<string> source, int n)
            {
                foreach (var r in 选择n个元素(source, 2))
                {
                    if (n == 1)
                        yield return new List<IEnumerable<string>> { r };
                    else
                    {
                        var others = source.Except(r).ToList();
                        foreach (var x in N段两两组合(others, n - 1))
                        {
                            var result = new List<IEnumerable<string>> { r };
                            result.AddRange(x);
                            yield return result;
                        }
                    }
                }
            }        static IEnumerable<IEnumerable<string>> 选择n个元素(IEnumerable<string> source, int n)
            {
                if (source.Count() >= n)
                {
                    if (n == 1)
                    {
                        foreach (var r in source)
                            yield return new List<string> { r };
                    }
                    else if (n > 1)
                    {
                        var a = source.First();
                        var others = source.Skip(1).ToList();
                        foreach (var r in 选择n个元素(others, n - 1))
                        {
                            var result = new List<string> { a };
                            result.AddRange(r);
                            yield return result;
                        }
                        foreach (var r in 选择n个元素(others, n))
                            yield return r;
                    }
                }
            }
        }
    }
      

  3.   

    上面的算法,是求任意n段m个元素组合的结果,n和m可以自由改变。
      

  4.   

    例如,3段3个元素组合(排列),可以写using System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
                var cnt = 0;
                foreach (var r in N段三三组合(str, 3))
                {
                    Console.WriteLine($"第{++cnt}种组合:");
                    foreach (var d in r)
                        Console.Write($" {string.Join("|", d)} ");
                    Console.WriteLine();
                }
                Console.WriteLine("..............按任意键结束");
                Console.ReadKey();
            }        static IEnumerable<IEnumerable<IEnumerable<string>>> N段三三组合(IEnumerable<string> source, int n)
            {
                foreach (var r in 选择n个元素(source, 3))
                {
                    if (n == 1)
                        yield return new List<IEnumerable<string>> { r };
                    else
                    {
                        var others = source.Except(r).ToList();
                        foreach (var x in N段三三组合(others, n - 1))
                        {
                            var result = new List<IEnumerable<string>> { r };
                            result.AddRange(x);
                            yield return result;
                        }
                    }
                }
            }        static IEnumerable<IEnumerable<string>> 选择n个元素(IEnumerable<string> source, int n)
            {
                if (source.Count() >= n)
                {
                    if (n == 1)
                    {
                        foreach (var r in source)
                            yield return new List<string> { r };
                    }
                    else if (n > 1)
                    {
                        var a = source.First();
                        var others = source.Skip(1).ToList();
                        foreach (var r in 选择n个元素(others, n - 1))
                        {
                            var result = new List<string> { a };
                            result.AddRange(r);
                            yield return result;
                        }
                        foreach (var r in 选择n个元素(others, n))
                            yield return r;
                    }
                }
            }
        }
    }
      

  5.   

    05,06|01,02|03,04
    05,06|03,04|01,02
    确定是两种组合方式?            var str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
                var res = new List<string>();
                foreach (var a in str.Combination(2))
                {
                    foreach (var b in str.Except(a).Combination(2))
                    {
                        foreach (var c in str.Except(a).Except(b).Combination(2))
                        {
                            var t = new List<string>();
                            t.Add(string.Join(",", a));
                            t.Add(string.Join(",", b));
                            t.Add(string.Join(",", c));
                            res.Add(string.Join("|", t));
                        }
                    }
                }
                foreach(var x in res) Console.WriteLine(string.Join(",", x));
      

  6.   

    比如说打印前 100 个结果,可以写using System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
                var cnt = 0;
                foreach (var r in N段组合(str, 3).Take(100))
                    Console.WriteLine($"第{++cnt}种组合:{string.Join("|", r.Select(d => string.Join(",", d)))}");
                Console.WriteLine("..............按任意键结束");
                Console.ReadKey();
            }        static IEnumerable<IEnumerable<IEnumerable<string>>> N段组合(IEnumerable<string> source, int n)
            {
                foreach (var r in 选择n个元素(source, 2))
                {
                    if (n == 1)
                        yield return new List<IEnumerable<string>> { r };
                    else
                    {
                        var others = source.Except(r).ToList();
                        foreach (var x in N段组合(others, n - 1))
                        {
                            var result = new List<IEnumerable<string>> { r };
                            result.AddRange(x);
                            yield return result;
                        }
                    }
                }
            }        static IEnumerable<IEnumerable<string>> 选择n个元素(IEnumerable<string> source, int n)
            {
                if (source.Count() >= n)
                {
                    if (n == 1)
                    {
                        foreach (var r in source)
                            yield return new List<string> { r };
                    }
                    else if (n > 1)
                    {
                        var a = source.First();
                        var others = source.Skip(1).ToList();
                        foreach (var r in 选择n个元素(others, n - 1))
                        {
                            var result = new List<string> { a };
                            result.AddRange(r);
                            yield return result;
                        }
                        foreach (var r in 选择n个元素(others, n))
                            yield return r;
                    }
                }
            }
        }
    }这里通过改变2和3两个数字可以灵活改变选择,这里体现了两个算法分别设计。
      

  7.   


    结果代码并不是重点,重点在于,从这里可以看出你没有学过 .net 的迭代器模式。这个是比较大的缺陷!!
      

  8.   

    嗯,修正一下:这里使用的迭代器是 c# 特性,不是 .net 的特性。
      

  9.   


    结果代码并不是重点,重点在于,从这里可以看出你没有学过 .net 的迭代器模式。这个是比较大的缺陷!!是的,老师。谢谢老师的点评
      

  10.   

    老师,为啥,我用到我的代码里,第一层的Combination会报错,而第二层,第三层的却没有,怎么回事呢?
      

  11.   

    确定,有使用using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
      

  12.   

    平时要注意收集各种算法的实现,写成扩展以备不时之需    static class Extend
        {
            /// <summary>
            /// 笛卡尔积
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sequences"></param>
            /// <returns></returns>
            public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
            this IEnumerable<IEnumerable<T>> sequences)
            {
                IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
                return sequences.Aggregate(
                  emptyProduct,
                  (accumulator, sequence) =>
                    from accseq in accumulator
                    from item in sequence
                    select accseq.Concat(new[] { item }));
            }
            /// <summary>
            /// 组合
            /// </summary>
            /// <typeparam name="TValue"></typeparam>
            /// <param name="values"></param>
            /// <param name="num"></param>
            /// <returns></returns>
            public static IEnumerable<IEnumerable<TValue>> Combination<TValue>(
                this IEnumerable<TValue> values,
                //            Int32 count,
                Int32 num)
            {
                var t = Enumerable.Range(0, num).ToList();
                do
                {
                    yield return values.Where((x, i) => t.Contains(i));
                }
                while (NextCombination(t, values.Count(), num));
            }
            /// <summary>
            /// C(n,m) 的下一项
            /// </summary>
            /// <param name="ar"></param>
            /// <param name="num"></param>
            /// <param name="k"></param>
            /// <returns></returns>
            public static bool NextCombination(List<int> ar, int n, int m)
            {
                if (ar.Count() != m) ar = Enumerable.Range(0, m).ToList();
                bool changed = false, finished = false;
                if (m > 0)
                {
                    for (int i = m - 1; !changed && !finished; i--)
                    {
                        if (ar[i] < (n - 1) - (m - 1) + i)
                        {
                            ar[i]++;
                            if (i < m - 1)
                            {
                                for (int j = i + 1; j < m; j++)
                                {
                                    ar[j] = ar[j - 1] + 1;
                                }
                            }
                            changed = true;
                        }
                        finished = (i == 0);
                    }
                }
                return changed;
            }
            public static IEnumerable<IEnumerable<TValue>> Permutation<TValue>(
                this IEnumerable<TValue> values )
            {
                var t = Enumerable.Range(0, values.Count()).ToList();
                var p = values.ToList();
                do
                {
                    yield return t.Select(i => p[i]);
                }
                while (NextPermutation(t));
            }
            /// <summary>
            /// P(n) 的下一项
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            public static bool NextPermutation(List<int> a)
            {
                int first = 0;
                int last = a.Count;
                int c, j, m, n;            int i = last;
                i--;
                while (true)
                {
                    var t = i;
                    i--;
                    if (a[i] < a[t])
                    {
                        j = last;
                        while (!(a[i] < a[--j])) ;
                        c = a[i];
                        a[i] = a[j];
                        a[j] = c;
                        m = t;
                        n = last - 1;
                        while (m < n)
                        {
                            c = a[n];
                            a[n] = a[m];
                            a[m] = c;
                            m++;
                            n--;
                        }
                        return true;
                    }
                    if (i == first)
                    {
                        m = first;
                        n = last - 1;
                        while (m < n)
                        {
                            c = a[n];
                            a[n] = a[m];
                            a[m] = c;
                            m++;
                            n--;
                        }
                        return false;
                    }
                }
            }
        }
      

  13.   

    算法,乃至于说到“简单算法”,其实就是首先把递归学好,然后就是学过迭代器(编程语法)并且能用来实现递归算法(递归化迭代),就可以了。比如说打印2个元素的组合,代码using System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> str = new List<string> { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
                var cnt = 0;
                foreach (var r in 选择n个元素(str, 2))
                    Console.WriteLine($"第{++cnt}种组合: {string.Join(",", r)}");
                Console.WriteLine("..............按任意键结束");
                Console.ReadKey();
            }        static IEnumerable<IEnumerable<string>> 选择n个元素(IEnumerable<string> source, int n)
            {
                if (source.Count() >= n)
                {
                    if (n == 1)
                    {
                        foreach (var r in source)
                            yield return new List<string> { r };
                    }
                    else if (n > 1)
                    {
                        var a = source.First();
                        var others = source.Skip(1);
                        foreach (var r in 选择n个元素(others, n - 1))
                        {
                            var result = new List<string> { a };
                            result.AddRange(r);
                            yield return result;
                        }
                        foreach (var r in 选择n个元素(others, n))
                            yield return r;
                    }
                }
            }
        }
    }这里的组合算法就是递归的:假设要从k个元素中查找n个元素组合,只要你能找出k-1个元素中的n-1中组合就可以了。同样地查找 k 个元素分为n段输出的结果,那么只要你能先找出一段输出,然后在剩下的元素中找出n-1段输出就可以了。static IEnumerable<IEnumerable<IEnumerable<string>>> N段组合(IEnumerable<string> source, int n)
    {
        foreach (var r in 选择n个元素(source, 2))
        {
            if (n == 1)
                yield return new List<IEnumerable<string>> { r };
            else
            {
                var others = source.Except(r);
                foreach (var x in N段组合(others, n - 1))
                {
                    var result = new List<IEnumerable<string>> { r };
                    result.AddRange(x);
                    yield return result;
                }
            }
        }
    }学过算法或者数据结构课程的人应该非常容易理解“算法”,没学过的就比较困难。而使用迭代器不过是小伎俩,知道 c# 语言有这么优雅的迭代器技术就可以了。关键还是算法递归的规则先要明白。
      

  14.   


    去 python 论坛问。
      

  15.   

    基本 python 还没有学,就说 python 能用来“改进”c# 代码,这是什么思路?