2012-12-21 72 views
0

我想不出一個好辦法做到這一點:遍歷所有配置

我通過6個數字,加起來21號的所有coombinations要循環必須大於0的整數。

例如:

21 0 0 0 0 0 
20 1 0 0 0 0 
20 0 1 0 0 0 
... 
1 2 3 4 5 6 
etc... 

你們可以給我一個線索?

回答

2

這個問題類似於next_permutation問題。 https://github.com/zwxxx/LeetCode/blob/master/Next_Permutation.cpp。我們可以通過修改如何獲得下一個元素來解決這個問題。以下是一個示例代碼。

#include <iostream> 

using namespace std; 

bool findNext(int *perm) 
{ 
    if (perm[5] == 21) 
     return false; 
    int i; 
    for(i = 0; i < 6; i++) 
     if (perm[i] != 0) 
      break; 
    perm[i+1]++; 
    perm[i]--; 
    if (i > 0) { 
     int tmp = perm[i]; 
     perm[i] = perm[0]; 
     perm[0] = tmp;                                                      
    } 
    return true; 
} 

void printPerm(int *perm) 
{ 
    for (int i = 0; i < 6; i++) { 
     cout << perm[i] << " "; 
    } 
    cout << endl; 
} 

int main() 
{ 
    int n[6]; 
    n[0] = 21; 
    for (int i =1; i < 6; i++) 
     n[i] = 0; 
    printPerm(n); 
    while (findNext(n)) { 
     printPerm(n); 
    } 
    printPerm(n); 

} 
+0

工作完美,謝謝 – bdeonovic

+0

會有一個容易報告獨特的排列? – bdeonovic

+0

你的意思是隨機挑選一個合格的置換? – 2012-12-22 14:07:13

-1

你會想要六個嵌套循環(或遞歸函數),只要總和命中21你應該break循環。

1

爲第一個數字A選擇一個數字,然後找出5個數字的組合等於(21-A)等等,對於所有4等等的組合。 1個案例可以有(至多)1個組合。爲了保持獨特性,你可以添加數字必須非增

約束,因此會去是這樣的:

findcombinations(sum, length, max) { 

if(length == 1) 
    return 1; 
else { 
    for(int i = 0; i <= sum && i <= max; i++) 
     return findcombinations(sum - i; length -1; i) 
} 
} 
+0

+1,但OP的例子表明,他不*不*需要獨特的設置。此外,您的退貨聲明中的標點符號是錯誤的(至少對於我每天使用的任何語言)。 [哦,如果你*要產生獨特的集合,我會按升序來做,而不是降序,這簡化了'for'子句的一個比較:'for(int i = min; i <= sum ; ++ i)'只是一個念頭。] – rici

0

我希望下一個排列方法。 或者你可以使用蠻力與6嵌套for循環更容易實現。

這裏的下一步置換的C#版本從成義,他的帖子

using System; 
using System.Collections.Generic; 
using System.Linq; 

static class Extensions 
{ 
    public static string GetString(this IEnumerable<int> arr) 
    { 
     return arr.Aggregate("", (a, b) => a + " " + b); 
    } 
} 

class Program 
{ 
    const int Sum = 21; 
    const int Len = 6; 

    static void Main(string[] args) 
    { 
     var result = new List<string>(); 
     Run(result); 
     result.ForEach(Console.WriteLine); 

     Console.WriteLine(string.Format("N: {0}\nPress a key to exit", 
      result.Count)); 
     Console.ReadKey(); 
    } 

    static void Run(IList<string> result) 
    { 
     var n = new int[Len]; 
     n[0] = Sum; 

     result.Add(n.GetString()); 
     while (FindNext(n)) 
     { 
      result.Add(n.GetString()); 
     } 
    } 

    static bool FindNext(IList<int> perm) 
    { 
     if (perm.Last() == Sum) 
     { 
      return false; 
     } 

     int i; 
     for (i = 0; i < Len; i++) 
     { 
      if (perm[i] != 0) 
      { 
       break; 
      } 
     } 

     perm[i + 1]++; 
     perm[i]--; 
     if (i > 0) 
     { 
      int tmp = perm[i]; 
      perm[i] = perm[0]; 
      perm[0] = tmp; 
     } 
     return true; 
    } 
} 

轉換的蠻力版本會是這樣在C#

static void Main(string[] args) 
{ 
    var result = new List<string>(); 
    for (int a = 0; a <= Sum; a++) 
     for (int b = 0; b <= Sum; b++) 
      for (int c = 0; c <= Sum; c++) 
       for (int d = 0; d <= Sum; d++) 
        for (int e = 0; e <= Sum; e++) 
         for (int f = 0; f <= Sum; f++)        
          if(a+b+c+d+e+f==Sum)         
           result.Add(string.Format(
            "{0} {1} {2} {3} {4} {5}", 
             a,b,c,d,e,f)); 

    result.ForEach(Console.WriteLine);        
    Console.WriteLine(string.Format("N: {0}\nPress a key to exit", 
            result.Count)); 
    Console.ReadKey(); 
}