求一算法答案

luck0235 2016-08-22 04:59:51
一个简单的类

class item
{
public string name { get; set; }
public int level { get; set; }
}


构造演示数据

List<item> all = new List<item>();
all.Add(new item { name = "Red", level = 0 });
all.Add(new item { name = "Blue", level = 0 });

all.Add(new item { name = "S", level = 1 });
all.Add(new item { name = "M", level = 1 });
all.Add(new item { name = "L", level = 1 });

all.Add(new item { name = "Man", level = 2 });
all.Add(new item { name = "Woman", level = 2 });


算法要求根据level分组进行所有name的组合,结果如下:
Red - S - Man
Red - S - Woman
Red - M - Man
Red - M - Woman
Red - L - Man
Red - L - Woman
Blue - S - Man
Blue - S - Woman
Blue - M - Man
Blue - M - Woman
Blue - L - Man
Blue - L - Woman

如果level最大值固定的话没有问题,比如level最大值为2我可以这样:

foreach(var _0 in all.Where(m => m.level == 0))
{
foreach(var _1 in all.Where(m => m.level == 1))
{
foreach(var _2 in all.Where(m => m.level == 2))
{
System.Console.WriteLine(_0.name + "-" + _1.name + "-" + _2.name);
}
}
}


现在关键问题是level最大值不固定,可能为2,可能为5,可能为10...... 请教如何用动态的方式完成这样的组合?
PS:设定level以1递增,可用for(int i = 0; i < level; i++)的方式遍历level
很多年没来CSDN了,不知现在CSDN比Stackoverflow如何,谢谢各位
...全文
417 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
luck0235 2016-09-03
  • 打赏
  • 举报
回复
TKS各位,这是一个笛卡尔算法问题,因为项目中是用JS来实现,后来花了不少时间来做这个算法,还是感谢各位热心回复,也贴上我的最终结果:

public class Main
    {
        /// <summary>
        /// 笛卡尔乘积的递归方法
        /// </summary>
        /// <param name="result">结果</param>
        /// <param name="data">数据集</param>
        /// <param name="level">递增维度</param>
        /// <param name="path">中间值</param>
        static void Recursive(List<string> result, List<List<string>> data, int level, string path)
        {
            if (level >= data.Count)
            {
                result.Add(path);
                return;
            }
            foreach (var item in data[level])
                Recursive(result, data, level + 1, path == null ? item : path + "-" + item);
        }

        public void Go()
        {
            List<List<string>> data = new List<List<string>>();

            List<string> dataItem1 = new List<string>();
            dataItem1.Add("Red");
            dataItem1.Add("Blue");
            data.Add(dataItem1);

            List<string> dataItem2 = new List<string>();
            dataItem2.Add("S");
            dataItem2.Add("M");
            dataItem2.Add("L");
            data.Add(dataItem2);

            List<string> dataItem3 = new List<string>();
            dataItem3.Add("Man");
            dataItem3.Add("Woman");
            data.Add(dataItem3);

            List<string> result = new List<string>();
            Recursive(result, data, 0, null);

            foreach (var s in result)
                System.Console.WriteLine(s);
        }

    }//end class
xuzuning 2016-08-23
  • 打赏
  • 举报
回复
求笛卡尔积,一般用递归
引用 14 楼 twotuli_software 的回复:
锻炼下思想嘛。万一改用java实现呢。
维秀斯丢丢 2016-08-23
  • 打赏
  • 举报
回复
锻炼下思想嘛。万一改用java实现呢。
摇撼大地 2016-08-23
  • 打赏
  • 举报
回复
引用 12 楼 twotuli_software 的回复:
我觉得大家不能以来就用 .net自带的 算法。 要自己看如何实现,利用c#.
不要重复发明轮子。 不过你说的也没错呢。 但是他们用的.net基础类库的方法,其实都不很复杂。只是把一些模式化的工作简化了而已。 Linq完全可以用for循环来做。但是非要自己弄就很没有意义了呢。。。。。 lambda表达式也可以自己做一个委托。但是那样写起来的代码长的吓死人呢。反正两个写法生成的IL代码都一样的。干嘛不简单一点呢。
维秀斯丢丢 2016-08-23
  • 打赏
  • 举报
回复
我觉得大家不能以来就用 .net自带的 算法。 要自己看如何实现,利用c#.
摇撼大地 2016-08-23
  • 打赏
  • 举报
回复
引用 9 楼 luck0235 的回复:
项目中是一个Javascript的实现,我尝试下怎么用for循环来实现,TKS starfd .
引用 8 楼 lyj224170707 的回复:
别问为什么。。就是这么任性。。多少组都可以。。算法不用改


       class item
        {
            public string name { get; set; }
            public int level { get; set; }
        }

        static void Main(string[] args)
        {
            List<item> all = new List<item>();
            all.Add(new item { name = "Red", level = 0 });
            all.Add(new item { name = "Blue", level = 0 });

            all.Add(new item { name = "S", level = 1 });
            all.Add(new item { name = "M", level = 1 });
            all.Add(new item { name = "L", level = 1 });

            all.Add(new item { name = "Man", level = 2 });
            all.Add(new item { name = "Woman", level = 2 });
            var r = all.GroupBy(x => x.level)
                       .Select(x => x.Select(y => y.name))
                       .Aggregate((a, b) => a.SelectMany(x => b.Select(y => x + "-" + y)))
                       .ToList();
        }

鼓掌~~~Aggregate我还是不太会用呢
游离失所 2016-08-22
  • 打赏
  • 举报
回复
想到笛卡尔积,首先想到SelectMany。 想到多个组合而成,自然就想到Aggregate。 一句话就能搞定的问题
luck0235 2016-08-22
  • 打赏
  • 举报
回复
项目中是一个Javascript的实现,我尝试下怎么用for循环来实现,TKS starfd .
游离失所 2016-08-22
  • 打赏
  • 举报
回复
别问为什么。。就是这么任性。。多少组都可以。。算法不用改


       class item
        {
            public string name { get; set; }
            public int level { get; set; }
        }

        static void Main(string[] args)
        {
            List<item> all = new List<item>();
            all.Add(new item { name = "Red", level = 0 });
            all.Add(new item { name = "Blue", level = 0 });

            all.Add(new item { name = "S", level = 1 });
            all.Add(new item { name = "M", level = 1 });
            all.Add(new item { name = "L", level = 1 });

            all.Add(new item { name = "Man", level = 2 });
            all.Add(new item { name = "Woman", level = 2 });
            var r = all.GroupBy(x => x.level)
                       .Select(x => x.Select(y => y.name))
                       .Aggregate((a, b) => a.SelectMany(x => b.Select(y => x + "-" + y)))
                       .ToList();
        }

摇撼大地 2016-08-22
  • 打赏
  • 举报
回复
晚上回去我也写一个。看看能不能实现。下班喽~~~
摇撼大地 2016-08-22
  • 打赏
  • 举报
回复
引用 4 楼 starfd 的回复:
List<item> all = new List<item>();
all.Add(new item { name = "Red", level = 0 });
all.Add(new item { name = "Blue", level = 0 });

all.Add(new item { name = "S", level = 1 });
all.Add(new item { name = "M", level = 1 });
all.Add(new item { name = "L", level = 1 });

all.Add(new item { name = "Man", level = 2 });
all.Add(new item { name = "Woman", level = 2 });

var gps = all.GroupBy(i => i.level).ToList();
var result = gps[0].Select(i => i.name).ToList();
for (var j = 1; j < gps.Count; j++)
{
    result = (from r in result
                from t in gps[j]
                select r + "-" + t.name).ToList();
}
foreach (var r in result)
{
    Console.WriteLine(r);
}
鼓掌。不过我更喜欢用.方法调用Linq。感觉sql语句形式的理解不能。。。。。
维秀斯丢丢 2016-08-22
  • 打赏
  • 举报
回复
public static List<List<T>> CartesianProduct<T>(this List<List<T>> lstSplit)
        {
            int count = 1;
            lstSplit.ForEach(item => count *= item.Count);
            //count = lstSplit.Aggregate(1, (result, next) => result * next.Count);
            var lstResult = new List<List<T>>();
            for (int i = 0; i < count; ++i)
            {
                var lstTemp = new List<T>();
                int j = 1;
                lstSplit.ForEach(item =>
                {
                    j *= item.Count;
                    lstTemp.Add(item[(i / (count / j)) % item.Count]);
                });
                lstResult.Add(lstTemp);
            }
            return lstResult;
        }
  • 打赏
  • 举报
回复
List<item> all = new List<item>();
all.Add(new item { name = "Red", level = 0 });
all.Add(new item { name = "Blue", level = 0 });

all.Add(new item { name = "S", level = 1 });
all.Add(new item { name = "M", level = 1 });
all.Add(new item { name = "L", level = 1 });

all.Add(new item { name = "Man", level = 2 });
all.Add(new item { name = "Woman", level = 2 });

var gps = all.GroupBy(i => i.level).ToList();
var result = gps[0].Select(i => i.name).ToList();
for (var j = 1; j < gps.Count; j++)
{
    result = (from r in result
                from t in gps[j]
                select r + "-" + t.name).ToList();
}
foreach (var r in result)
{
    Console.WriteLine(r);
}
mislrb 2016-08-22
  • 打赏
  • 举报
回复
建议将这些建成表格T1,T2,T3,....., 然后写个动态存储过程判断T开头的表格有几个,然后用无连接的select语句如:select a.idxcode,b.code,c.code from bomdb.dbo.Process a,bomdb.dbo.defcode b,bomdb.dbo.causecode c即可得到所有可能的组合了,仅供参考
luck0235 2016-08-22
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
这东西就是笛卡尔乘积…… Linq完美支持 首先你的代码都是同一个类,只是通过level 进行区分,所以首先就是list.GroupBy(r=>r.level ) 然后就是foreach进行linq的笛卡尔乘积
请给实现代码,谢谢
  • 打赏
  • 举报
回复
这东西就是笛卡尔乘积…… Linq完美支持 首先你的代码都是同一个类,只是通过level 进行区分,所以首先就是list.GroupBy(r=>r.level ) 然后就是foreach进行linq的笛卡尔乘积

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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