#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