由于深度递归而导致堆栈溢出
Stack overflow due to deep recursion
我有一个任务来解决硬币变化问题,如下所示: 我有 5 种类型的硬币 {1,5,10,25,50},我们想用给定数量的钱对这些硬币进行更改,例如,我可以通过多少种方式形成 11 美分,或者一般的 n 美分?我的程序应该能够处理高达 7489 美分作为输入。
我使用递归和动态编程来解决问题,但在运行时出现堆栈溢出错误(输入>= 3980(
如何解决此错误?
#include <iostream>
using namespace std;
typedef long long ll;
int Cents[5] = { 1,5,10,25,50 }, in, mem[5][7495];
ll CC(int i, int val) { // this is where the recursion happens
if (val == 0) return 1;
if (i == 5) return 0;
if (mem[i][val] != -1) return mem[i][val];
long long op1 = CC(i + 1, val);
long long op2 = Cents[i] <= val ? CC(i, val - Cents[i]) : 0;
return mem[i][val] = (op1+op2);
}
int main() { // here i pass an input and fill the mem 2d array with -1's
scanf_s("%d", &in);
memset(mem, -1, sizeof mem);
printf("%lldn", CC(0, in));
system("pause");
return 0;
}
例如,如果输入为 5,则输出应为 2 路 (1(,(5( 如果为 11,则为 4 (1*11(,(1*6,5*1(,(10*1,1*1(,(1*1,5*2( 等等。
您有一个堆栈溢出,因为您的递归深度仅受数组大小和便士数量的限制。 而且您的堆栈状态大小合理。
一种解决方案是使用显式堆栈。
enum coins {
penny, nickle, dime, quarter, half,
coin_count
};
enum {
max_cash = 7495
};
struct coin_problem {
coins lowest_coin = penny;
int money = 0;
};
struct coin_cache {
unsigned long long solution[coin_count][max_cash+1];
coin_cache(){
for(auto& row:solution)
for(auto& val:row)
val=-1;
}
unsigned long long& set(coin_problem p){
return solution[p.lowest_coin][p.money];
}
unsigned long long get(coin_problem p)const{
if(p.lowest_coin==coin_count) return 0;
if(p.money==0) return 0;
return solution[p.lowest_coin][p.money];
}
};
unsigned long long count_solutions( std::vector<coin_problem>& vec, coin_cache& cache){
unsinged long lon retval = 0;
while(!vec.empty()){
auto cur = vec.back();
retval = cache.get[cur];
if (retval != -1) {
vec.pop_back();
continue;
}
++cur.lowest_coin;
auto op1 = cache.get[cur];
if (op1 == -1) vec.push_back(cur);
--cur.lowest_coin;
unsigned long long op2 = -1;
if(Cents[cur.lowest_coin] <= cur.money){
cur.money -= Cents[cur.lowest_coin];
op2 = cache.get[cur];
if (op2==-1) vec.push_back(cur);
cur.money += Cents[cur.lowest_coin];
} else {
op2 = 0;
}
if (op1 != -1 && op2 != -1){
retval = cache.set(cur) = op1+op2;
vec.pop_back();
}
}
return retval;
}
unsigned long long count_solutions( coin_problem p ){
auto pcache = std::make_unique<coin_cache>();
std::vector<coin_problem> todo = {p};
return count_solutions( todo, *pcache );
}
我撕毁了你的递归解决方案并给了它一个手动堆栈。
对于问题堆栈中的每个条目,我们首先查看缓存中是否有解决方案在等待。 如果是这样,我们计算它,并将其存储在缓存中,然后弹出问题。 如果问题堆栈为空,我们将其返回。
如果没有,如果堆栈,我们将首先解决的子问题推到顶部,将当前的问题留待以后解决,并循环直到堆栈为空。
由于我们的手动堆栈存在于免费商店(也称为堆(上,因此我们不太可能在桌面系统上遇到堆栈溢出。
这并不完全有效,因为我们可以在堆栈上为每个问题提供多个条目。 但这最多应该是一个固定因素,并且可以通过重新排序"递归"以首先执行"最深"调用来解决。 或者使问题堆栈成为一组按深度排序的问题。
另一种方法是先解决表中的每个条目,最深的。
相关文章:
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- C++ 对象数组堆栈溢出
- 有没有一种方法可以捕获进程中的堆栈溢出?C++Linux
- 对象接收堆栈溢出异常 c++ 的排序向量
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- C++ 中递归期间的堆栈溢出
- 启动 dll 时 C# 环境堆栈溢出
- 在C++中使用数组时如何防止堆栈溢出?
- 如何修复递归函数导致的堆栈溢出错误?C++
- 当我尝试为结构分配新指针时出现堆栈溢出错误
- 为什么析构函数无休止地调用自己(导致堆栈溢出)?
- 为什么堆栈溢出?如有建议,不胜感激
- 主函数执行时C++堆栈溢出异常
- 如何在不导致堆栈溢出的情况下计算非常大的数字和很小的 HCF.我正在使用欧几里得算法
- 我正在尝试使用回溯来解决 N queen 问题,但在编译时它会给出运行时错误(动态堆栈缓冲区溢出)
- 如何在Windows上报告堆栈缓冲区溢出
- 如何抑制来自 gcc 中地址清理器的堆栈缓冲区溢出
- 声明大数组时堆栈/堆溢出
- c++中栈溢出和分段错误的危险