新手 求助 二维数组按条件排列组合 想的头疼

wx9288 2020-08-26 10:47:53
有一个二维数组 [四行四列]【每行已经从小到大排序好】

4, 5, 6, 7 ‘--第一行
1, 2, 4, 8 ‘--第二行
9, 10, 11, 12 '--第三行
3, 13, 21, 22 '--第四行

正常组合是有256种组合
现在是想每一行的值跟下一行对比 如果比下一行小就组合,不是就抛弃,每行组合之后得出最终组合数

例如第一行第一个为 4 第二行除了8 其他都不匹配,得出
4,8
然后从第二行8跟下一行匹配,第三行都比8大 得出
4,8,9 |4,8,10| 4,8,11| 4,8,12
之后第四行 3 比 第三行的所有元素都小,其他都大 最后得出最终组合
4,8,9 ,13 |4,8,9 ,21 |4,8,9 ,22
4,8,10 ,13 |4,8,10 ,21 |4,8,10 ,22
4,8,11 ,13 |4,8,11 ,21 |4,8,12 ,22
4,8,12 ,13 |4,8,12 ,21 |4,8,12 ,22

然后再以此类推取第一行的5来跟下面比较。

如5开头 结果要为 5,8,9,13 | 5,8,9,21 | 5,8,9,22
5,8,10,13 | 5,8,10,21 | 5,8,10,22
5,8,11,13 | 5,8,11,21 | 5,8,11,22
5,8,12,13 | 5,8,12,21 | 5,8,12,22


求各位指点下算法



...全文
2593 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wx9288 2020-08-27
  • 打赏
  • 举报
回复
谢谢 @wanghui0380 和 @正怒月神 两位大神 指点
  • 打赏
  • 举报
回复
依据列出来的最终结果是有规律可循的大约有个流程,应该是可以编写出来的,不需要想很多,只要一步步调试到实现一步步的步骤,直到整个完成。
wanghui0380 2020-08-26
  • 打赏
  • 举报
回复
so,把这代码一写,你会发现其实用传统递归也是一样
  Dictionary<int, List<int>> dic = new Dictionary<int, List<int>>();
            List<int> a1 = new List<int>() { 4, 5, 6, 7 };
            List<int> a2 = new List<int>() { 1, 2, 4, 8 };
            List<int> a3 = new List<int>() { 9, 10, 11, 12 };
            List<int> a4 = new List<int>() { 3, 13, 21, 22 };

            dic.Add(1, a1);
            dic.Add(2, a2);
            dic.Add(3, a3);
            dic.Add(4, a4);
            Action<List<int>> call = null;
            call = lst =>
            {
               
                if (lst.Count == 4)
                {
                    Console.WriteLine(string.Join(",", lst));

                }
                else
                {
                    int last = lst.Last();
                    var lst2 = dic[lst.Count+1].Where(c => c > last);
                    foreach (var i in lst2)
                    {
                        var newlist = new List<int>(lst);
                        newlist.Add(i);
                        call(newlist);
                    }
                }
            };

            call(new List<int>{5});
当然,我个人说别太过纠结,最原始的笛卡儿积是最好的,你也看到了。上面那个linq 就是循环256次,而我后面怎么写其实都不会比他更好,因为where难道不需要循环?同时我还得构造递归的参数,so,别总跟XX园学习纠结。现在的XX园那么多别的语种的好思想,好手段不学。整天跟XX园那波玩net的学纠结可不是好习惯
wanghui0380 2020-08-26
  • 打赏
  • 举报
回复
这种玩意,如果严格按照你的想法做,其实仿神经网络有向图可以玩,我懒得动用那种玩意,就使用rx自然订阅构建有向处理,反正就是个数1,传递给个数2,传递给个数3,到个数4拼接输出 代码
   Subject<List<int>> subject = new Subject<List<int>>();
            List<int> a1 = new List<int>() { 4, 5, 6, 7 };
            List<int> a2 = new List<int>() { 1, 2, 4, 8 };
            List<int> a3 = new List<int>() { 9, 10, 11, 12 };
            List<int> a4 = new List<int>() { 3, 13, 21, 22 };


			subject.Where(p => p.Count == 4).Subscribe(p =>
            {
				Console.WriteLine(string.Join(",",p));
            });

            subject.Where(p => p.Count == 1).Subscribe(p =>
            {
                var temp = p.Last();
                var target = a2.Where(c => c > temp);
				foreach (var i in target)
                {
                    List<int> lst = new List<int>(p);
                    lst.Add(i);
                    subject.OnNext(lst);

                }

            });
            subject.Where(p => p.Count == 2).Subscribe(p =>
            {
                var temp = p.Last();
                var target = a3.Where(c => c > temp);
                foreach (var i in target)
                {
                    List<int> lst = new List<int>(p);
                    lst.Add(i);
                    subject.OnNext(lst);

                }

            });

            subject.Where(p => p.Count == 3).Subscribe(p =>
            {
                var temp = p.Last();
                var target = a4.Where(c => c > temp);
                foreach (var i in target)
                {
                    List<int> lst = new List<int>(p);
                    lst.Add(i);
                    subject.OnNext(lst);

                }

            });

			subject.OnNext(new List<int>{5});
			Console.ReadKey();
结果
引用
5,8,9,13 5,8,9,21 5,8,9,22 5,8,10,13 5,8,10,21 5,8,10,22 5,8,11,13 5,8,11,21 5,8,11,22 5,8,12,13 5,8,12,21 5,8,12,22
wanghui0380 2020-08-26
  • 打赏
  • 举报
回复
不想折腾,简单算 笛卡尔集直接算,然后过滤掉非递增序列 简单直白的做,不想废脑浆。否则得搞啥,递归迭代传递参数,毕竟他会变成兔子队列,差分序列(后项依赖前项的最后值) h
正怒月神 2020-08-26
  • 打赏
  • 举报
回复
static void Main(string[] args)
        {
            List<int> a1 = new List<int>() { 4,5,6,7};
            List<int> a2 = new List<int>() { 1,2,4,8 };
            List<int> a3 = new List<int>() { 9,10,11,12 };
            List<int> a4 = new List<int>() { 3, 13, 21, 22 };

            var q = from x1 in a1
                    from x2 in a2
                    from x3 in a3
                    from x4 in a4
                    where x1<x2 && x2<x3 && x3<x4
                    select $"{x1},{x2},{x3},{x4}";

            Console.WriteLine(q.Count());
            Console.WriteLine("==============");
            Console.WriteLine(string.Join(" \r\n", q));

            Console.ReadLine();
        }
  • 打赏
  • 举报
回复
按这样规律只能找到9个?

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧