需要重构深度嵌套代码的帮助

发布于 2024-11-16 03:21:00 字数 1491 浏览 0 评论 0原文

#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;
}
#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

罪#恶を代价 2024-11-23 03:21:00
if(range>i)

为什么不直接在 range 处启动 i 来避免这个问题呢?哦,我的想法是倒退的,但重点是——你可以轻松地重构这是 for 条件的一部分。不需要额外的条件。

if(j>i)

为什么不直接在 i 处启动 j 呢?

...(对其他两个循环重复)

这消除了一半的嵌套。就循环本身而言,我建议对其使用提取方法。

if(range>i)

Why not just start i at range and avoid the problem? Oh, I had that backwards, but the point stands -- you can easily refactor this to be part of the for condition. No need for an extra conditional.

if(j>i)

Why not just start j at i?

... (Repeat for the other two loops)

That gets rid of half your nesting. As far as the loops themselves go, I would suggest using Extract Method on them.

飘过的浮云 2024-11-23 03:21:00

您可以做的第一件事是使用继续

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
    }
}

这将大大减少嵌套,并且在我看来提高可读性。

The first thing you can do is 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
    }
}

This will greatly reduce nesting and IMO improve readability.

相思碎 2024-11-23 03:21:00

就像重构任何东西一样。你首先要弄清楚什么
代码正在做。在这种情况下,许多测试都是无关紧要的,并且
每个循环基本上都做同样的事情。你已经解决了一个非常
更普遍问题的具体情况(非常草率)。锻炼
该问题的通用算法将导致更干净、更简单的结果
解决方案,并且是一种更通用的解决方案。像这样的:

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++。我想一旦你习惯了它们,你就会发现它们很多
更容易推理。

The same way you refactor anything. You first have to figure out what
the code is doing. In this case, many of the tests are irrelevant, and
each of the loops does basically the same thing. You've solved one very
specific case (very sloppily) of a more general problem. Working out
the general algorithm for the problem will result in a cleaner, simpler
solution, and one that is more general. Something like this:

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;
}

The only thing really worthy of comment in the above is the calculation
of limit in calc, and that's really just an optimization; you could
use n and get the same results (but you'd recurse a bit more).

You'll note that in your original versions, the end conditions of the
loops are more or less arbitrary: using range systematically would
work, or you could work out the formula which I use for limit (which
would result in a different end condition for each loop.

Also, my code uses the half open intervals which are ubiquious in C and
C++. I think that once you get used to them, you'll find them much
easier to reason about.

囚你心 2024-11-23 03:21:00

我的 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(" ");
    }

My C++ is rusty, so let me give you a C# example. Any number of nested loops can be replaced with just one, as follows:

    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(" ");
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文