【问题标题】:Recursion Stack Overflow C++递归堆栈溢出 C++
【发布时间】:2017-01-20 07:33:57
【问题描述】:

我是 C++ 新手,但认为解决一些项目 Euler 问题会让我熟悉该语言。

尝试时 Project Euler Problem 14: Longest Collatz sequence

我无法让我的 C++ 解决方案工作,但我的 python 解决方案没有问题...

import time 
start = time.time()
memo = {1:1,2:2}
longest_chain, longest_starting_key = 2, 2

def rec(a):
    global longest_chain, longest_starting_key

    if a in memo.keys():
        return memo[a]    
    if a % 2 == 0:
        memo[a] = rec(a // 2) + 1
    else:
        memo[a] = rec(3 * a + 1) + 1
    if memo[a] > longest_chain:
        longest_chain = memo[a]
        longest_starting_key = a
    return memo[a]    

for i in range(1000000,3,-1): rec(i)

print("starting key", longest_starting_key , ": has length", longest_chain)
print((time.time() - start), "seconds")

得到了

starting key 837799 has length 525
1.399820327758789 seconds

我的 C++ 尝试...(我认为是等效的...)

#include <iostream>
#include <unordered_map>
std::unordered_map<int, int> mem = { {1,1},{2,2} };
int longest_chain{ 2 }, best_starting_num{ 2 };

bool is_in(const int& i){
    auto search = mem.find(i);
    if(search == mem.end())
        return false;
    else
        return true;
}

int f(int n){
    if(is_in(n))
        return mem[n];
    if(n % 2)
        mem[n] = f(3 * n + 1) + 1;
    else
        mem[n] = f(n / 2) + 1;
    if(mem[n] > longest_chain)
        longest_chain = mem[n];
    return mem[n];
}

int main(){
    for(int i = 3; i < 1000000; i++){
        f(i);
    }
    std::cout << longest_chain << std::endl;
}

在调试模式下在 Visual Studio 中运行时,出现以下错误

Unhandled exception at 0x00007FF75A64EB70 in
0014_longest)collatz_sequence_cpp.exe: 0xC00000FD: Stack overflow
(parameters: 0x0000000000000001, 0x000000DC81493FE0).

有人告诉我应该使用指针在堆上分配,但使用指针的经验非常有限......

我不明白的另一件事是......当我在主体循环中使用 100'000 而不是 1'000'000 运行它时,它可以工作但很慢。

【问题讨论】:

  • 通过 vc++ 调试器运行它会有很大帮助。我认为mem 已经在堆中分配了新元素。
  • 当我在我的系统上运行你的 C++ 代码时,我得到 489(不是 525)的结果。 Python 和 C++ 版本显然不是等价的……
  • @Barry 下面提供了一个非常好的算法答案,但在您的 C++ 版本中也存在编码错误 - 只要存在值,您就会进行两次地图查找,首先是检测它的可用性,其次是实际得到它。不好。
  • Collatz这个词搜索SO是值得的。

标签: c++ visual-c++ recursion stack-overflow


【解决方案1】:

提示:Collat​​z 序列(数学上)提供的n 范围内的不变量是什么,您的Python 代码满足而您的C++ 代码不满足?提示提示:在实际发生堆栈溢出之前,n 的最后几个值是什么?

【讨论】:

  • 啊,正是我要说的,但提示格式更符合问题上下文的教育主题。 :)
  • 我一直盯着它看,但无济于事。我将 python 版本中的主循环更改为看起来像 C++ 版本(而不是从 1 倒计时到 999'999)。更改了名称,使它们看起来更像彼此......但我仍然无法发现它。
  • @Quantifeye 从113383 开始。你用f 调用的n 的所有值是什么?
猜你喜欢
  • 2016-11-11
  • 2015-04-04
  • 2018-12-02
  • 2017-09-06
  • 2019-07-08
  • 2015-08-05
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多