心血来潮,写了个N阶乘小程序,在大于10000的时候,抛出了java.lang.StackOverflowError错误.估计是递归嵌套太多所造成的.后来上网搜索了一下,发现果然是这个原因.
为了简化这个问题描述,另外写了段非常简单测试.public class T { int max;
T(int i){
max = i;
}
void Recursive(int i){
if(i > 0)
Recursive(--i);
else
return; }
public static void main(String[] args){
T t= new T(100000);//10000没有问题,加上个0就有问题了
t.Recursive(t.max);
}
}我想请问各位,有没有办法能够加深STACK的长度.
(java -Xss128m T 我已经试过了,似乎没有作用,bea的解释是java栈有两种,java 和c的.这个参数只能对c的栈起作用).我想,之所以用递归,就是因为大家不知道程序执行的深度是多少.那怎么样解决递归所带来的这个运行错误呢?如果实在有必要转换成非递归方法,请各位高手为小弟指条N阶乘的算法思想吧.
为了简化这个问题描述,另外写了段非常简单测试.public class T { int max;
T(int i){
max = i;
}
void Recursive(int i){
if(i > 0)
Recursive(--i);
else
return; }
public static void main(String[] args){
T t= new T(100000);//10000没有问题,加上个0就有问题了
t.Recursive(t.max);
}
}我想请问各位,有没有办法能够加深STACK的长度.
(java -Xss128m T 我已经试过了,似乎没有作用,bea的解释是java栈有两种,java 和c的.这个参数只能对c的栈起作用).我想,之所以用递归,就是因为大家不知道程序执行的深度是多少.那怎么样解决递归所带来的这个运行错误呢?如果实在有必要转换成非递归方法,请各位高手为小弟指条N阶乘的算法思想吧.
for(;i>0;i--){
...;
}
}
for循环就行了,递归不是你那么用的。
zhuyf333:谢谢你提示for循环,我只是觉得好像没有看懂我的问题,我的意思是在必须递归解决问题的时候,如何控制其不让JVM崩掉。所以我举出的只是一个模型。要求:精确测出10000左右的N阶乘(再大了咱们先不提)
我的N阶乘思路:
1)双向环形链表2)每个节点存贮一段数据(选取的是max=99999,想想原因?)3)节点乘以n,有进位,则进位与下一位相加,(有必要递归进位相加);若到头,新建节点4)遍历链表,依次输出到txt文本(注意不足6位要补0)。问题就出在递归,在9000左右还能正常且较快速执行,10000就StackOverflowError了。汗~~~
我只是想问清楚有没有办法扩大JVM对stack的限制。
就算OS 没有限制,RAM也有极限。
就算你用的虚拟内存,那硬盘空间也有限制。所以,像你这种问题是不可能解决的。
确实有你说的问题
csdn上 不是星星的回答基本上不用看
XX太多了
好像你头上也没顶颗星星吧。
if (n < 0) {
return -1;
}
if (n == 0 || n == 1) {
return 1;
}return n * factoriell(n -1);
}如果你真要求1000的阶乘的话,用原始类型,那么c, c++, java都帮不了你,必须得用数组来存储计算结果才行。这个东西讲起来就有些麻烦了,可以到网上搜索一下怎么处理计算大数的程序,应该就知道办法了。或者好像ruby的数字处理不限大小,大可直到内存存不下,也许你真要这样做,可以试一下。
强烈反对用递归来做阶乘问题和神奇数字(斐波那契数列)问题的。有循环放着不用,用这个简直是在糟蹋程序,并且糟蹋硬件。不管在任何地方,任何语言,递归都是尽量避免使用的。虽然没有goto那么明确,但是肯定是说过,尽量避免使用。更没有你这么用的。
不过这样也告诉我们一个教训:使用递归的时候,一定要记得检测内存,及时抛出异常,否则程序中止丢失数据了,可是影响了程序的健壮性的。
恩,好的,谢谢你的忠告。的确,我感觉也是,在递归面前就是脆弱的羔羊。不知道什么时候就会被搞死。我正在改写我那段程序,使其在可预计和控制的有限次递归或循环中结束。