论坛首页 Java企业应用论坛

解决万恶的大数问题

浏览 4635 次
精华帖 (2) :: 良好帖 (3) :: 新手帖 (3) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-02   最后修改:2009-02-04

由于电脑的智商有限啊 我的智商是没问题的
呵呵 大数问题一直困扰着我 不只是我阿 身边的同学作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
   发表时间:2009-02-03  
ACM里面有很多大数问题,可能问题简单,但是结果出乎你的意料。。。
C做大数运算是一件很有挑战性的事情
最普通的做法就是利用数组,最普遍最基础的题目就是算1000!结果了
算法是可行的,只是需要很多优化
比如动态预测数组空间,避免重复运算什么的
0 请登录后投票
   发表时间:2009-02-03  
leeldy 写道
ACM里面有很多大数问题,可能问题简单,但是结果出乎你的意料。。。
C做大数运算是一件很有挑战性的事情
最普通的做法就是利用数组,最普遍最基础的题目就是算1000!结果了
算法是可行的,只是需要很多优化
比如动态预测数组空间,避免重复运算什么的

呵呵。acm都是那帮牛人们的事情。
上次我离散数学老师还和我们说了有一个算法。听得云里雾里的。
他说用字符串来弄。好像还要用到什么二进制的知识……
3 请登录后投票
   发表时间:2009-02-04  
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?
0 请登录后投票
   发表时间: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
1 请登录后投票
   发表时间:2009-02-04  
cpdw 写道
楼主的这个算法有错误啊,当算比较小的数值的阶乘时没有问题,超过某一个值(我没有验证),结果就不对了,例如你自己的例子:35!,正确结果应该是:10333147966386144929666651337523200000000,你这明显有问题,看看哪里有问题?


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


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

不是数组大小的问题,我数组设在400算35!就有问题,是算法的问题,你的程序如果数组不够大,不会自动舍去,而会抛出数组越界的异常,你查查看,35!的正确结果确实应该是10333147966386144929666651337523200000000
我验证了下,26之前的结果都是正确的,从27开始,结果就开始错了,你查下
1 请登录后投票
   发表时间: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;  
#                     }
4 请登录后投票
   发表时间:2009-02-25   最后修改:2009-02-25

改进你的算法,提高效率

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 <= n; i++) {
			for (int j = 1; j <= weishu; j++) {
				date[j] = date[j] * i;
			}

			// 确保除最高位外的每位不大于9
			for (int j = 1; j < weishu; j++) {
				if (date[j] >= 10) {
					date[j + 1] += date[j] / 10;
					date[j] = date[j] % 10;
				}
			}
			//确保最高位不大于9
			while (date[weishu] >= 10) {
				weishu++;
				date[weishu] += date[weishu - 1] / 10;
				date[weishu - 1] = date[weishu - 1] % 10;
			}
		}
		
		System.out.print(n + "!= ");
		for (int k = weishu; k >= 1; k--) {
		System.out.print(date[k]);
		}
		System.out.println("");

	}

}

 

2 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics