超大数解决方法

在练习算法的过程中又学到了新的知识点。今天在运行一个算法题时,过程没问题,就是数字太大了放不下而报错,比如100!

题目如下:
一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积。阶乘的增长速度非常快,例如,13!就已经比较大了,已经无法存放在一个整型变量中;而35!就更大了,它已经无法存放在一个浮点型变量中。因此,当n比较大时,去计算n!是非常困难的。幸运的是,在本题中,我们的任务不是去计算n!,而是去计算n!最右边的那个非0的数字是多少。例如,5!=12345=120,因此5!最右边的那个非0的数字是2。再如,7!=5040,因此7!最右边的那个非0的数字是4。再如,15!= 1307674368000,因此15!最右边的那个非0的数字是8。请编写一个程序,输入一个整数n(0<n<=100),然后输出n!最右边的那个非0的数字是多少。
输入:
  7
输出:
  4
  尝试几个小的数的时候还可行,计算结果太大的时候就不行了


import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        BigInteger sum= BigInteger.ONE;
        for(int i=1;i<=n;i++){
            sum=sum.multiply(BigInteger.valueOf(i));
        }
        String s=String.valueOf(sum);
        int length=s.length();
        int[] arr=new int[length];
        for(int j=0;j<length;j++){
            arr[j]=s.charAt(length-1-j)-48;
        }
        int m=0;
        while(arr[m]==0){
            m++;
        }
        System.out.println(arr[m]);
    }
}

还有昨天的另一道题
定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。

例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入一个正整数n,你的任务是判断它是否是17的倍数。
输入:输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=10^100),表示待判断的正整数。n=0表示输入结束,你的程序不应当处理这一行。
输出:对于每组测试数据,输出一行,表示相应的n是否是17的倍数。1表示是,0表示否。
当输入:1717171717171717171717171717171717171717171717171718时,会因为数据太大而报错因此,也需要使用BigInteger方法

import java.math.BigInteger;
import java.util.Scanner;

public class Main27 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int arr[]=new int[10];
        String a;
        int n=0;
        while (true) {
            a = sc.nextLine();
            if(a.equals("0")){
                break;
            }
            BigInteger b=new BigInteger(a);
            //得到个位数字并×5
            int ge=5*Integer.parseInt(a.substring(a.length()-1));
            //去掉个位数的部分。用输入的数字除以10,因为是BigInteger之间的运算所以用以下方法
            BigInteger zhengshu=b.divide(BigInteger.valueOf(10));
            if(zhengshu.subtract(BigInteger.valueOf(ge)).remainder(BigInteger.valueOf(17)).equals(BigInteger.valueOf(0))){
                arr[n]=1;
            }else{
                arr[n]=0;
            }
            n++;
        }
        for(int i=0;i<n;i++){
            System.out.println(arr[i]);
        }
    }
}

这里用到了BigInteger方法,下面整理一下


BigInteger abs()  返回大整数的绝对值
BigInteger add(BigInteger val) 返回两个大整数的和
BigInteger and(BigInteger val)  返回两个大整数的按位与的结果
BigInteger andNot(BigInteger val) 返回两个大整数与非的结果
BigInteger divide(BigInteger val)  返回两个大整数的商
double doubleValue()   返回大整数的double类型的值
float floatValue()   返回大整数的float类型的值
BigInteger gcd(BigInteger val)  返回大整数的最大公约数
int intValue() 返回大整数的整型值
long longValue() 返回大整数的long型值
BigInteger max(BigInteger val) 返回两个大整数的最大者
BigInteger min(BigInteger val) 返回两个大整数的最小者
BigInteger mod(BigInteger val) 用当前大整数对val求模
BigInteger multiply(BigInteger val) 返回两个大整数的积
BigInteger negate() 返回当前大整数的相反数
BigInteger not() 返回当前大整数的非
BigInteger or(BigInteger val) 返回两个大整数的按位或
BigInteger pow(int exponent) 返回当前大整数的exponent次方
BigInteger remainder(BigInteger val) 返回当前大整数除以val的余数
BigInteger leftShift(int n) 将当前大整数左移n位后返回
BigInteger rightShift(int n) 将当前大整数右移n位后返回
BigInteger subtract(BigInteger val)返回两个大整数相减的结果
byte[] toByteArray(BigInteger val)将大整数转换成二进制反码保存在byte数组中
String toString() 将当前大整数转换成十进制的字符串形式
BigInteger xor(BigInteger val) 返回两个大整数的异或
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值