停止回溯

发布于 2024-08-30 01:12:20 字数 89 浏览 9 评论 0原文

C/C++ 中是否有任何方法可以在找到第一个解决方案后停止回溯算法而不退出程序。

我希望我的函数立即退出该函数,而不是一一退出每一级递归并声明返回。

Is there any way in C/C++ to stop a backtracking algorithm after finding the first solution without exiting the program.

I want my function to immediately exit the function,not to quit every level of recurrsion one by one stating return.

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

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

发布评论

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

评论(8

挥剑断情 2024-09-06 01:12:20

一种快速而肮脏的方法是抛出异常并在基础级别捕获它(现在很多人会尖叫只使用异常来处理错误,我认为,找到一个解决方案是一个特殊的事件,因为找不到一个解决方案就是规范)

A quick and dirty way is to throw an Exception and catch it at the base level (around right now a lot of people will scream to only use Exceptions for Errors, I argue, founding a solution is an exceptional event since not finding one is the norm)

计㈡愣 2024-09-06 01:12:20

如果您在完成后设置了一个标志,然后在您的函数中检查该标志,您可以解决这个问题。例如

void foo(..)
{
   if (g_done) return;
...
}

if you have a flag that is set when you are done and then which is checked in your functions you could solve this. e.g.

void foo(..)
{
   if (g_done) return;
...
}
一杯敬自由 2024-09-06 01:12:20

在不确切知道您需要什么的情况下,我会考虑实现您自己的堆栈,并完全避免递归。这样,退出回溯树(单个“返回”)就变得微不足道,并且还可以通过再次调用该函数来恢复搜索以找到下一个解决方案,假设保留了用户定义堆栈的状态(在静态变量中)。当然,将简单的递归程序转换为循环需要一些编程开销,但做起来非常简单。

Without knowing exactly what you need, I would look at implementing your own stack, and avoid recursion completely. That way it becomes trivial to exit the backtracking tree (a single "return"), and it is also possible to resume the search to find the next solution by calling the function again, presuming the state of the user-defined stack is preserved (in static variables). Of course, there is a bit of programming overhead to convert a simple recursive program to a loop, but it's pretty straightforward to do.

那些过往 2024-09-06 01:12:20

它实际上取决于您的实现,但您可以设置一些特殊参数并将其用作标志,例如“我们得到解决方案了吗?如果是,则中止当前例程并仅获取输出的解决方案”。

It actually depends on your implementation, but you could set some special param and use it as a flag like "Did we get a solution? If yes, then abort your current routine and get only that solution to the output".

給妳壹絲溫柔 2024-09-06 01:12:20

为什么要让函数立即退出呢?不回溯堆栈是危险的,因为堆栈上可能有需要销毁的对象。抛出异常可能会给你带来麻烦,它会清理堆栈。提供有关您正在尝试执行的操作的更多信息,我们也许可以提供其他方法。

Why do you want the function to immediately exit? Not backtracking through the stack is dangerous as you could have objects on it that need to be destroyed. Throwing an exception might due the trick for you, and it will cleanup the stack. Provide more information about what you are trying to do and we might be able to provide other approaches.

み青杉依旧 2024-09-06 01:12:20

您可以在 C 和 C++ 中使用 setjmp()/longjmp() 作为一种粗略但有效的方法来绕过一路传递标志的需要。

You could use setjmp()/longjmp() in both C and C++ for a crude but effective way of bypassing the need to pass a flag all the way back.

策马西风 2024-09-06 01:12:20

如果你的回溯算法实际上递归得足够深,以至于这很重要,那么你不应该使用递归,因为你将面临堆栈崩溃的危险。您应该考虑使用自己的堆分配堆栈(存储表示状态的 POD 对象)将算法重写为迭代方法,而不是犯下涉及 longjmp 的暴行。当您找到解决方案时,可以通过一个有效的步骤销毁状态容器并返回答案。

请参阅从递归到迭代的方式

If your backtracking algorithm is actually recursing deep enough for this to matter, you shouldn't use recursion because you'll be in danger of blowing the stack. Rather than committing some atrocity involving longjmp, you should consider rewriting your algorithm to an iterative approach with your own heap-allocated stack which stores a POD object representing the state. When you find your solution the state container can be destroyed in one efficient step and the answer can be returned.

See Way to go from recursion to iteration

夏末的微笑 2024-09-06 01:12:20

首先,请注意,您不能对任何递归函数执行此操作。
考虑以下代码:

int SumNum(int nMax)
{
    if (0 == nMax)
        return 0;
    else
        return nMax + SumNum(nMax-1);
}

实际值是在回溯期间计算的。

但是,您可以按以下方式重写代码:

int SumNum(int nMax, int nSum)
{
    if (0 == nMax)
        return nSum;
    else
        return SumNum(nMax-1, nSum+nMax);
}

现在,您可以执行以下技巧:

    int SumNum(int nMax, int nSum)
    {
        if (0 == nMax)
            throw nSum;
        else
            return SumNum(nMax-1, nSum+nMax);
    }


f()
{
        int nSum;

        try
        {
            SumNum(100, 0);
        }
        catch (int _nSum)
        {
            nSum= _nSum;
        }
}

First, note that you can not do it for any recursive function.
Consider the following code:

int SumNum(int nMax)
{
    if (0 == nMax)
        return 0;
    else
        return nMax + SumNum(nMax-1);
}

The actual value is calculated during the backtracking.

However, you can rewrite the code in the following way:

int SumNum(int nMax, int nSum)
{
    if (0 == nMax)
        return nSum;
    else
        return SumNum(nMax-1, nSum+nMax);
}

Now, you can do the following trick:

    int SumNum(int nMax, int nSum)
    {
        if (0 == nMax)
            throw nSum;
        else
            return SumNum(nMax-1, nSum+nMax);
    }


f()
{
        int nSum;

        try
        {
            SumNum(100, 0);
        }
        catch (int _nSum)
        {
            nSum= _nSum;
        }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文