#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;
}
回答
你可以做的第一件事是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
}
}
这将大大减少嵌套和国际海事组织提高可读性。
你可以这样做。或者你可以消除完全冗余的IF测试(正如我所说的......)。 +1,因为这可以更普遍地解决问题,但我认为针对这种特定情况存在更好的解决方案。 –
代码不可读,不可维护。第一个是比利·奥尼尔所说的:消除不必要的“如果”。 (对于它的价值,第一个如果总是假的。) –
@James Kanze:我同意这些检查是不必要的,但我建议的重构可以正式完成,并且可以更容易地注意到这些检查是不必要的。 – sharptooth
if(range>i)
为什么不刚开始哦,我已经倒过来了,但问题依然存在 - 您可以轻松地将此重构为i
在range
,避免这个问题?for
条件的一部分。不需要额外的条件。
if(j>i)
为什么不开始j
在i
?
...(重复其他两个环路)
这摆脱了一半的嵌套。就循环本身而言,我会建议对它们使用提取方法。
+1:此外,'i'将始终小于'range'。 –
与重构任何东西的方式相同。你首先要弄清楚代码在做什么 。在这种情况下,许多测试都是不相关的,并且每个循环基本上都是相同的。你已经解决了一个非常普遍的问题的特定情况(很滑稽)。计算出 问题的一般算法将产生更简洁,更简洁的解决方案,而且更通用。事情是这样的:
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++ ubiquious。我认为,一旦你习惯了它们,你会发现他们更 容易推理。
我的C++ i生锈的,所以让我给你一个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(" ");
}
- 1. 需要帮助排序深层嵌套值的PHP数组
- 2. STI帮助。需要帮助重构我现有的代码
- 3. 需要帮助AngularJS深层过滤
- 4. 需要帮助来重构嵌套的if else语句
- 5. 需要帮助使'嵌套'的WPF ItemsControl
- 6. 需要LINQ重构帮助
- 7. Javascript需要重构帮助
- 8. 需要帮助简化,重复代码
- 9. 需要帮助减少重复代码
- 10. 需要Android代码帮助
- 11. 需要javascript代码帮助
- 12. 需要xslt代码帮助
- 13. C代码需要帮助
- 14. 需要帮助穿越嵌套散列
- 15. 需要帮助嵌套兄弟
- 16. 在angularJs嵌套路由帮助需要
- 17. 帮助重构PHP代码
- 18. JQuery的重构需要帮助
- 19. 需要重构此功能的帮助
- 20. 在3层实体类对象的代码需要帮助
- 21. 需要分层帮助
- 22. 需要帮助理解的C代码
- 23. 需要帮助的小代码
- 24. 需要帮助,过时的代码
- 25. htaccess的需要帮助纠正代码
- 26. 需要帮助的PHP获取代码
- 27. 需要帮助的这个C++代码
- 28. 需要帮助的理解代码
- 29. 需要帮助,简单的表代码
- 30. 需要关于Java代码的帮助
意外标记为C.对不起! – GENRO