2014-03-19 78 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