`
radovi
  • 浏览: 64264 次
  • 性别: Icon_minigender_1
  • 来自: 杭 州
社区版块
存档分类
最新评论

解决万恶的大数问题

阅读更多

由于电脑的智商有限啊 我的智商是没问题的
呵呵 大数问题一直困扰着我 不只是我阿 身边的同学作acm的问题 也一直有大树问题  呵呵

其实 java中早就有现成的解决方法了的
在java的math的包下面有BigInteger和BigDecimal两个类 可以用来解决部分大数问题 而且相当之精确

这里 从数据结构的角度出发  一维数组也可以解决大数问题

如下

# /**   
#  * ***********CopyRight**************   
#  *-------Powered by QianXunNet-----   
#  *-----Version 1.1   2009-01-22-----    
#  *-----   Design BY  NiChao    -----   
#  *^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   
#  */ 
package array;
import java.util.*;
public class nc030 {

   
    public static void main(String[] args) throws Exception {   
        // TODO Auto-generated method stub

        int[] date=new int[100];        //可以存放40个数字
        date[1]=1;
        int weishu=1;                     //求出来的值得位数
       
        System.out.println("------用数组解决大数问题---------");
        System.out.println("检验对象:求n!的值");
        System.out.println("input the n=");
       
        Scanner cin=new Scanner(System.in);
       
        int n=cin.nextInt();
         int i=1;
        for(i=1; i<=n;i++){
            for(int j=1;j<=weishu;j++)
                   date[j]=date[j]*i;
            for(int j=1;j<=weishu;j++ )
            {
                if(date[j]>=10)    // 原本此处及下面无等号 多谢好心的网友把我的程                                   //序测试了几组数据,我才回过头来检查谢谢了。
                    for(int r=1;r<=weishu;r++)
                    {
                        if(date[weishu]>=10)
                            weishu++;
                        date[r+1]=date[r+1]+date[r]/10;    //这里有很多次在做无用功  值得改进 
                        date[r]=date[r]%10;
                    }
            }
        }
       
        System.out.print(i-1+"!= ");
        for(int k=weishu;k>=1;k--)
        {
            System.out.print(date[k]);
        }
        System.out.println("");
       
    }

}


运行结果如下
------用数组解决大数问题---------
检验对象:求n!的值
input the n=
35
35!= 10333147966386144929666651337523200000000
分享到:
评论
9 楼 czan.ok 2009-02-25  
学习,路过
8 楼 haisheng 2009-02-25  
<p>改进你的算法,提高效率 </p>
<pre name="code" class="java">import java.util.Scanner;

public class nc030 {

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub

int[] date = new int[100000];
date[1] = 1;
int weishu = 1; // 求出来的值的位数

System.out.println("------用数组解决大数问题---------");
System.out.println("求n!的值");
System.out.print("n=");

Scanner cin = new Scanner(System.in);

int n = cin.nextInt();
for (int i = 1; i &lt;= n; i++) {
for (int j = 1; j &lt;= weishu; j++) {
date[j] = date[j] * i;
}

// 确保除最高位外的每位不大于9
for (int j = 1; j &lt; weishu; j++) {
if (date[j] &gt;= 10) {
date[j + 1] += date[j] / 10;
date[j] = date[j] % 10;
}
}
//确保最高位不大于9
while (date[weishu] &gt;= 10) {
weishu++;
date[weishu] += date[weishu - 1] / 10;
date[weishu - 1] = date[weishu - 1] % 10;
}
}

System.out.print(n + "!= ");
for (int k = weishu; k &gt;= 1; k--) {
System.out.print(date[k]);
}
System.out.println("");

}

}
</pre>
<p> </p>
7 楼 radovi 2009-02-04  
cpdw 写道

radovi 写道cpdw 写道楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?

不是 对的呀 我把数组的大小开大后 还是这个值呀 35!= 15002590386144929666651337523200000000
不是数组大小的问题,我数组设在400算35!就有问题,是算法的问题,你的程序如果数组不够大,不会自动舍去,而会抛出数组越界的异常,你查查看,35!的正确结果确实应该是10333147966386144929666651337523200000000
我验证了下,26之前的结果都是正确的,从27开始,结果就开始错了,你查下



搞得我晚饭都没怎么安心的吃啊!唉!算是解决了。   是我的算法有错误 首先先谢谢阁下能真么认真的看我的程序   上面代码中我已经修改了    

# if(date[j]>10)  
#                     for(int r=1;r<=weishu;r++)  
#                     {  
#                         if(date[weishu]>10)  
#                             weishu++;  
#                         date[r+1]=date[r+1]+date[r]/10;              //这里有很多次在做无用功  值得改进   
#                         date[r]=date[r]%10;  
#                     }  

这块语句出错了 data[j]>=10 以及 data[weishu]>=10

如下
# if(date[j]>=10)  
#                     for(int r=1;r<=weishu;r++)  
#                     {  
#                         if(date[weishu]>=10)  
#                             weishu++;  
#                         date[r+1]=date[r+1]+date[r]/10;              //这里有很多次在做无用功  值得改进   
#                         date[r]=date[r]%10;  
#                     }
6 楼 cpdw 2009-02-04  
radovi 写道
cpdw 写道
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?


不是 对的呀 我把数组的大小开大后 还是这个值呀 35!= 15002590386144929666651337523200000000

不是数组大小的问题,我数组设在400算35!就有问题,是算法的问题,你的程序如果数组不够大,不会自动舍去,而会抛出数组越界的异常,你查查看,35!的正确结果确实应该是10333147966386144929666651337523200000000
我验证了下,26之前的结果都是正确的,从27开始,结果就开始错了,你查下
5 楼 radovi 2009-02-04  
cpdw 写道
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?


不是 对的呀 我把数组的大小开大后 还是这个值呀 35!= 15002590386144929666651337523200000000
4 楼 radovi 2009-02-04  
cpdw 写道
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?


嗯嗯 是的 谢谢你了

确实错了
如果要算35!的阶乘 应该将数组的大小开大点

上面代码中
       int[] date=new int[40];        //可以存放40个数字  
       date[1]=1;  


35!之所以错 就是因为他舍掉了几位数字


上次测试的时候就是没写上异常处理 所以即使他数组越界了 我没有发现 我改了
将以下这部分改进
#    public static void main(String[] args) {  
#         // TODO Auto-generated method stub  


3Q
3 楼 cpdw 2009-02-04  
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?
2 楼 radovi 2009-02-03  
leeldy 写道
ACM里面有很多大数问题,可能问题简单,但是结果出乎你的意料。。。
C做大数运算是一件很有挑战性的事情
最普通的做法就是利用数组,最普遍最基础的题目就是算1000!结果了
算法是可行的,只是需要很多优化
比如动态预测数组空间,避免重复运算什么的

呵呵。acm都是那帮牛人们的事情。
上次我离散数学老师还和我们说了有一个算法。听得云里雾里的。
他说用字符串来弄。好像还要用到什么二进制的知识……
1 楼 leeldy 2009-02-03  
ACM里面有很多大数问题,可能问题简单,但是结果出乎你的意料。。。
C做大数运算是一件很有挑战性的事情
最普通的做法就是利用数组,最普遍最基础的题目就是算1000!结果了
算法是可行的,只是需要很多优化
比如动态预测数组空间,避免重复运算什么的

相关推荐

Global site tag (gtag.js) - Google Analytics