2014-03-19 47 views
-6

我有以下类:有序唯一组合

internal class Course 
{ 
    public int CourseCode { get; set; } 
    public string DeptCode { get; set; } 
    public string Name { get; set; } 
} 

和下面的代码是2维数组我有:

Course[][] courses = new Course[3][]; 
courses[0] = new Course[] { 
    new Course() { CourseCode = 100, DeptCode = "EGR", Name = "EGR A" }, 
    new Course() { CourseCode = 100, DeptCode = "EGR", Name = "EGR B" } 
}; 

courses[1] = new Course[] { 
    new Course() { CourseCode = 200, DeptCode = "EN", Name = "EN A" } 
}; 

courses[2] = new Course[] { 
    new Course() { CourseCode = 300, DeptCode = "PHY", Name = "PHY A" } 
}; 

我想要做的就是让不同的组合,每个一个小组中的项目可以与其他小组一起处理;例如与前面的代码,结果将是:

1. EGR A - EN A - PHY A 
2. EGR B - EN A - PHY A 

回答: 要获得可能的组合的数量,我们可以使用Rule of Product,在上述情况下,可能的组合将是(2 * 1 * 1)= 2这确实是我上面写的两个组合。

LordTakkera给出了完美的答案,非常感谢!

+0

如果我让它看起来像我希望人们为我写代码,我很抱歉。我的第一个尝试是我编写了一个代码,在其中我有一个数组Course [],所有可能的课程没有分组。然后,我得到了所有可能的组合,在这种情况下,n是7,k是3. 然后,我筛选了所有结果,以将包含在一个组中的重复项删除,以避免在同一个数组中包含相同的类别课程。 虽然这是一个非常耗时的过程,所以我试着找到另一种方法来做到这一点,这是上面列出的一个方法。我尝试了很多for循环,但无法使其工作。 :/ – user3439065

回答

1

你可以使用嵌套的for循环:

for (int i = 0; i < courses[0].Length; i++) 
{ 
    for (int j = 0; j < courses[1].Length; i++) 
    { 
    for (int k = 0; k < courses[2].Length; i++) 
    { 
     //Do whatever you need with the combo, accessed like: 
     //courses[0][i], courses[1][j], courses[2][k] 
    } 
    } 
} 

当然,这种解决方案变得非常凌乱,你需要更多的嵌套。如果您需要深入研究,我会使用某种递归函数遍历集合并生成组合。

这将是这样的:

class CombinationHelper 
{ 
    public List<List<Course>> GetAllCombinations(Course[][] courses) 
    { 
      return GetCourseCombination(courses, 0); 
    } 

    public List<List<Course>> GetCourseCombination(Course[][] courses, int myIndex) 
    { 
     List<List<Course>> combos = new List<List<Course>>(); 

     for (int i = 0; i < courses[myIndex].Length; i++) 
     { 
      if (myIndex + 1 < courses.GetLength(0)) 
      { 
       foreach (List<Course> combo in GetCourseCombination(courses, myIndex + 1)) 
       { 
        combo.Add(courses[myIndex][i]); 
        combos.Add(combo); 
       } 
      } 
      else 
      { 
       List<Course> newCombination = new List<Course>() { courses[myIndex][i] }; 
       combos.Add(newCombination); 
      } 
     } 
     return combos; 
    } 
} 

我测试了这(对于“课程”代“诠释”,使核查更容易),它生产的所有8种组合(虽然不是为了,递归趋向于做如果我拿出订购代码,我会发布,但它不应该困难)。

递归函数对我来说已经够难了,所以我的解释不会很好。基本上,我们首先用“0”索引踢掉所有东西(以便我们从头开始)。然后我们迭代当前数组。如果我们不是“主”数组中的最后一个数组,那么我们就进入下一个子数组。否则,我们创建一个新的组合,添加它并返回。

由于递归堆栈“展开”,我们将生成的组合添加到我们的返回列表中,将其添加到它并再次返回。最终,整个事情“放松”,你剩下一个所有组合的清单。

同样,我相信这是一个非常混乱的解释,但递归算法(至少对我而言)本质上是混淆的。我会很乐意尝试阐述你想要的任何点。

+0

非常感谢!这个工作,但由于阵列是动态的,我不能依赖于编写2个嵌套循环,根据用户输入,它可能更多或更少,另外,你的意思是j ++和i ++,对吗?我的最终目标是通过课程[] []数组,并找到不同的独特组合,例如你提到的代码的作用,但对于任何数组维度。再次感谢:) – user3439065

+0

是的,我的意思是j ++和k ++。我会稍微发表一个递归表单的例子,这可能是你想要的方式。 – BradleyDotNET

+0

好吧,非常感谢!将等待这个例子:) – user3439065

1

在你的第二个指数看一看 - 0或1。如果你只看这一点,你看从0到7

计数为0〜7二进制数,把它转变为位,并得到你需要的组合模式。

+0

+1为调用按位操作,嵌套for循环可能会更简单一些:) – BradleyDotNET

+0

我不确定,我会把它留给OP。如果我是OP,我会用二进制表示去练习。 – zmbq

+0

非常感谢您的回答! :) 不幸的是,我不知道如何按位操作,所以我不知道如何把你的想法付诸实践。 如果你引导我走向正确的方向,我将不胜感激:) 谢谢! – user3439065