首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态笛卡儿积

动态笛卡儿积
EN

Stack Overflow用户
提问于 2016-08-22 10:04:49
回答 2查看 472关注 0票数 1

课堂演示:

代码语言:javascript
运行
复制
class item
{
    public string name { get; set; }
    public int level { get; set; }
}

数据演示:

代码语言:javascript
运行
复制
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 });

我需要由级别和组合所有名称组,这是笛卡尔产品问题。结果如下:

红S人 红S女 红-男 红-女 红人 红-女 蓝-S-人 蓝S女 蓝-男 蓝男-女 蓝-L-人 蓝-女

如果级别是固定的,则使用下面的代码解决:

代码语言:javascript
运行
复制
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))
        {
            Console.WriteLine(_0.name + "-" + _1.name + "-" + _2.name);
        }
    }
}

但最大的问题是:级别是动态的,我只是这样编码:

代码语言:javascript
运行
复制
for(int i = 0; i < level; i++)
{
    //some code ...
}

因为我真正的项目是Javascript,所以请给我简单的代码(非linq),非常感谢您的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-22 11:02:47

首先,我要建立一个清单,其中包含每个级别的项目:

代码语言:javascript
运行
复制
var levels = new List<List<item>>();
foreach (var item in all)
{
    while (levels.Count <= item.level)
        levels.Add(new List<item>());
    levels[item.level].Add(item);
}

然后使用简单的递归方法填充结果:

代码语言:javascript
运行
复制
var result = new List<string>();
AddCombinations(result, levels, 0, null);

如果该方法是:

代码语言:javascript
运行
复制
static void AddCombinations(List<string> result, List<List<item>> levels, int level, string path)
{
    if (level >= levels.Count)
    {
        result.Add(path);
        return;
    }
    foreach (var item in levels[level])
        AddCombinations(result, levels, level + 1, path == null ? item.name : path + " - " + item.name);
}

与递归不同,我可以调整实现,从我的答案到Every combination of "1 item from each of N collections",如果您愿意,可以迭代地构建结果,但是我认为上面的内容应该足够了。

票数 1
EN

Stack Overflow用户

发布于 2016-08-22 10:25:19

像这样的事情应该有效:

代码语言:javascript
运行
复制
var lines = CartesianProduct(all, 0);
foreach(var line in lines) {
   Console.WriteLine(line);
}

List<string> CartesianProduct(List<item> items, int level) {
   List<string> result = new List<string>();
   List<string> itemsOnThisLevel = new List<string>();
   foreach(var it in items) {
      if (it.level == level) itemsOnThisLevel.Add(it.name);
   }
   if (!itemsOnThisLevel.Any()) {
      result.Add("");
      return result;
   }
   var itemsOnLowerLevels = CartesianProduct(items, level+1);
   foreach(var it in itemsOnThisLevel) {
      foreach(var it2 in itemsOnLowerLevels) {
         result.Add(it2 + " - " + it);
      } 
   }
   return result
}

编辑:根据作者的要求删除linq表达式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39076649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档