Вопрос

Есть ли какие-либо способы в C / C ++, чтобы остановить алгоритм обратной передачи после нахождения первого решения, не выходящая в систему.

Я хочу, чтобы моя функция немедленно выйти из функции, чтобы не бросить каждый уровень рецензии один за другим возвращением.

Это было полезно?

Решение

Вы можете использовать setjmp () / longjmp () как в C, так и C ++ для неочищенного, но эффективного способа обхода необходимости передавать флаг весь путь назад.

Другие советы

Не зная, что именно вам нужно, я бы посмотрел на реализацию собственного стека и полностью избежать рекурсии. Таким образом, становится тривиальным для выхода из дерева Backtracking (один «возврат»), и также возможно возобновить поиск, чтобы найти следующее решение, вызывая функцию еще раз, предполагая, что состояние определенного пользователем стека сохраняется ( в статических переменных). Конечно, есть немного программирования накладных расходов, чтобы преобразовать простую рекурсивую программу в цикл, но это довольно просто сделать.

Быстрый и грязный способ - это выбросить исключение и поймать его на базовом уровне (вокруг прямо сейчас многие люди будут кричать, чтобы использовать только исключения для ошибок, я утверждаю, основание решения - исключительное событие, поскольку не находятся норма)

Если у вас есть флаг, который установлен, когда вы закончите, а затем проверяется в ваших функциях, вы можете решить это. например

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

Это на самом деле зависит от вашей реализации, но вы могли бы установить какой-то специальный параметр и использовать его как флаг, например, «Разве мы получили решение? Если да, то прерванию вашей текущей рутины и получите только это решение на вывод».

Почему вы хотите, чтобы функция немедленно выйти? Не возвращайтесь через стек опасно, поскольку вы можете иметь объекты на нем, что нужно уничтожить. Бросая исключение может быть из-за трюки для вас, и он очистят стек. Обеспечить дополнительную информацию о том, что вы пытаетесь сделать, и мы могли бы предоставить другие подходы.

Если ваш алгоритм Backtracking на самом деле речь достаточно глубоко, чтобы это было иметь значение, вы не должны использовать рекурсию, потому что вы будете в опасности продувать стек. Вместо того, чтобы совершить некоторую атроемность с участием LongJMP, вы должны рассмотреть вопрос о переписывании вашего алгоритма к итеративному подходу с вашим собственным стоком, выделенным кузочным, который хранит объект POD, представляющий состояние состояния. Когда вы найдете свое решение, состоятельный контейнер может быть уничтожен на одном эффективном этапе, и ответ может быть возвращен.

Видеть Способ перейти от рекурсии к итерации

Во-первых, обратите внимание, что вы не можете сделать это для любой рекурсивной функции. Рассмотрим следующий код:

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;
        }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top