f # stackoverflow проекта Эйлер # 4 - PullRequest
3 голосов
/ 13 сентября 2009

Я работаю над четвертой проблемой Project Euler и выполняю исключение stackoverflow. Я не прошу помощи в решении проблемы, я просто хотел бы, чтобы она объяснила , почему я получаю исключение stackoverflow. Обычно это происходит из-за бесконечной рекурсии, но я не верю, что на этот раз так (если я просто слепой и не вижу этого сейчас, пожалуйста, дайте мне знать).

Вот код:

let Euler4 =

let reverse sum =
    let rec loop (n,x) =
        if n = 0
        then
            x
        else
            loop (n/10,(x*10) + (n%10))

    loop (sum, 0);

let isPalindrome arg = (arg = (reverse arg));

let findPalindromes (startx,starty) =
    let rec loop (x,y) acc =
        let result = if isPalindrome (x * y) then ((x,y) :: acc) else acc;
        let next = match (x,y) with
            | (x,y) when y = 100 -> (x-1,starty)
            | _ -> (x,y-1)
        if x = 100 then
            result
        else
            loop (next) result

    loop (startx,starty) [];


let value = (999,999);
printfn "%A" (findPalindromes value);

;

Ответы [ 2 ]

10 голосов
/ 13 сентября 2009

Вы компилируете в режиме «Debug» или «Release»? В режиме отладки в VS хвостовые вызовы отключены по умолчанию (флаг компилятора "--tailcalls-"), чтобы сохранить стеки для отладки, но это имеет компромисс, который вы можете использовать для StackOverflow. Вы можете либо переключиться в режим «Release», либо

  • щелкните правой кнопкой мыши свойства проекта в обозревателе решений, выберите «Свойства»
  • перейти на вкладку «Сборка»
  • убедитесь, что выбрана конфигурация «Отладка»
  • установите флажок «Генерировать хвостовые вызовы»

для включения оконечных вызовов с настройками «Отладка».

(Ваша программа работает нормально для меня с включенными оконечными вызовами.)

0 голосов
/ 13 сентября 2009

Я не могу прочитать F # и не знаю, связана ли ваша проблема с этим, но особенно если вы делаете что-то рекурсивное, избегайте проверки на равенство числа, вместо этого попробуйте проверить порог. Например, вместо проверки n = 0, тест n <= 0. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...