#include <iostream>
using namespace std;
int main()
{
int range = 20;
int totalCombinations = 0;
for(int i=1; i<=range-2; i++)
{
if(range>i)
{
for(int j=1; j<=range-1; j++)
if(j>i)
{
for(int k=1; k<=range-1; k++)
if(k>j)
{
for(int l=1; l<=range-1; l++)
if(l>k)
{
for(int m=1; m<=range-1; m++)
if(m>l)
{
for(int f=1; f<=range; f++)
if(f>m)
{
cout << " " <<i<< " " <<j<< " " <<k<< " " <<l<< " " <<m<< " " <<f;
cin.get(); //pause
totalCombinations++;
}
}
}
}
}
}
}
cout << "TotalCombinations:" << totalCombinations;
}发布于 2011-06-20 16:16:19
你可以做的第一件事是using continue
for(int i=1; i<=range-2; i++) {
{
if(range<=i) {
continue;
}
for(int j=1; j<=range-1; j++) {
if(j<=i) {
continue;
}
//etc for all inner loops
}
}这将极大地减少嵌套并提高可读性。
发布于 2011-06-20 17:16:39
就像重构任何东西一样。您首先必须弄清楚代码在做什么。在这种情况下,许多测试都是无关紧要的,每个循环做的基本上都是一样的事情。您已经解决了一个非常具体的(非常草率的)更普遍的问题。计算出问题的通用算法将产生一个更干净、更简单的解决方案,而且更通用。如下所示:
class Combin
{
int m;
int n;
int total;
std::vector<int> values;
void calc();
void dumpVector() const;
public:
Combin( int m, int n ) : m(m), n(n), total(0) {}
int operator()() { total = 0; values.clear(); calc(); return total; }
};
void
Combin::calc()
{
if ( values.size() == m ) {
dumpVector();
++ total;
} else {
values.push_back( values.empty() ? 0 : values.back() + 1 );
int limit = n - (m - values.size());
while ( values.back() < limit ) {
calc();
++ values.back();
}
values.pop_back();
}
}
void
Combin::dumpVector() const
{
for (std::vector<int>::const_iterator iter = values.begin(); iter != values.end(); ++ iter )
std::cout << ' ' << *iter + 1;
std::cout << '\n';
}
int main()
{
Combin c( 6, 20 );
std::cout << "TotalCombinations:" << c() << std::endl;
return 0;
}上面唯一值得注意的是在calc中计算limit,这实际上只是一个优化;您可以使用n并获得相同的结果(但您会递归更多)。
您将注意到,在您的原始版本中,循环的结束条件或多或少是任意的:系统地使用range将会起作用,或者您可以计算出我用于limit的公式(这将为每个循环产生不同的结束条件。
此外,我的代码使用了在C和C++中普遍存在的半开区间。我认为,一旦你习惯了它们,你会发现它们更容易推理。
发布于 2011-06-21 04:06:26
我的C++已经生疏了,所以让我给您一个C#示例。可以将任意数量的嵌套循环替换为一个,如下所示:
public void ManyNestedLoopsTest()
{
var limits = new[] {2, 3, 4};
var permutation = new[] {1, 1, 0};
const int lastDigit = 2;
var digitToChange = lastDigit;
while(digitToChange >= 0)
{
if (permutation[digitToChange] < limits[digitToChange])
{
permutation[digitToChange]++;
digitToChange = lastDigit;
PrintPermutation(permutation);
continue;
}
permutation[digitToChange--] = 1;
}
}
private void PrintPermutation(int[] permutation)
{
for(int i=0;i<3;i++)
{
Console.Write(permutation[i]);
Console.Write(" ");
}
Console.WriteLine(" ");
}https://stackoverflow.com/questions/6408432
复制相似问题