我想不出一個好辦法做到這一點:遍歷所有配置
我通過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...
你們可以給我一個線索?
我想不出一個好辦法做到這一點:遍歷所有配置
我通過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...
你們可以給我一個線索?
這個問題類似於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);
}
你會想要六個嵌套循環(或遞歸函數),只要總和命中21你應該break
循環。
爲第一個數字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)
}
}
+1,但OP的例子表明,他不*不*需要獨特的設置。此外,您的退貨聲明中的標點符號是錯誤的(至少對於我每天使用的任何語言)。 [哦,如果你*要產生獨特的集合,我會按升序來做,而不是降序,這簡化了'for'子句的一個比較:'for(int i = min; i <= sum ; ++ i)'只是一個念頭。] – rici
我希望下一個排列方法。 或者你可以使用蠻力與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();
}
工作完美,謝謝 – bdeonovic
會有一個容易報告獨特的排列? – bdeonovic
你的意思是隨機挑選一個合格的置換? – 2012-12-22 14:07:13