java--BigInteger神器的开启姿势

在做到一些大数的题目的时候如果可以使用使用java或者python的话,那么这个问题就变成水题了,如果只能用C++的话,那么写个大数加减乘除的方法各个都可以超过100行的代码。
这里介绍了java中BigInteger的使用方法,顺便提及python相关的代码,以下面这道题目为例:

题目描述:

Today, facing the rapid development of business, SJTU recognizes that more powerful calculator should be studied, developed and appeared in future market shortly. SJTU now invites you attending such amazing research and development work. In most business applications, the top three useful calculation operators are Addition (+), Subtraction (-) and Multiplication (×) between two given integers. Normally, you may think it is just a piece of cake. However, since some integers for calculation in business application may be very big, such as the GDP of the whole world, the calculator becomes harder to develop. For example, if we have two integers 20 000 000 000 000 000 and 4 000 000 000 000 000, the exact results of addition, subtraction and multiplication are: 20000000000000000 + 4000000000000000 = 24 000 000 000 000 000 20000000000000000 - 4000000000000000 = 16 000 000 000 000 000 20000000000000000 × 4000000000000000 = 80 000 000 000 000 000 000 000 000 000 000 Note: SJTU prefers the exact format of the results rather than the float format or scientific remark format. For instance, we need “24000000000000000” rather than 2.4×10^16. As a programmer in SJTU, your current task is to develop a program to obtain the exact results of the addition (a + b), subtraction (a - b) and multiplication (a × b) between two given integers a and b.
输入描述:
Each case consists of two separate lines where the first line gives the integer a and the second gives b (|a| <10^400 and |b| < 10^400).
输出描述:
For each case, output three separate lines showing the exact results of addition (a + b), subtraction (a - b) and multiplication (a × b) of that case, one result per lines.
示例1
输入
复制
20000000000000000
4000000000000000
输出
复制
24000000000000000
16000000000000000
80000000000000000000000000000000

咋一看一道中规中矩的大数题,仔细一看竟然同时包括了+,-,×三种运算,显然出题人也不是要然你用C手敲每一行代码。如果还不会用java大数类的话那可能要损失1个亿啊。

java解法代码如下:

import java.util.Scanner;
import java.math.BigInteger;
public class Main{
    public static void main(String[] args){
        Scanner cin=new Scanner(System.in);
        while(cin.hasNext()){
            BigInteger a,b,c;
            a=cin.nextBigInteger();
            b=cin.nextBigInteger();
            System.out.println(a.add(b));
            System.out.println(a.subtract(b));
            System.out.println(a.multiply(b));
        }
    }
}

说到java那不得不再说说python老弟,简直偷懒得不要不要的,连数据类型都不用声明了,实际跑起来python的代码比java快了一些。但把python放在补充部分主要是因为现在大部分学校的机试只有极个别会有python的环境,但基本上java都会有,所以如果是为了应付机试的话,推荐以C/C++作为主要语言,然后辅助上java用来解决大数问题。

while True:
    try:
        a,b=int(input()),int(input())
        print(a+b)
        print(a-b)
        print(a*b)
    except:
        break

除了加减乘以外大数题中还有一类常出现的提醒–阶乘。其实阶乘本质上就是乘法运算的叠加。所以掌握了基本的乘法运算,阶乘运算也就自然而然地解决了,以下给出关于大数阶乘运算求解n!的代码。

package 大数阶乘;

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

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()) {
			BigInteger base = new BigInteger("1");
			BigInteger number = new BigInteger("1");
			int n = scanner.nextInt();
			for(int i=2;i<=n;i++) {
				number = number.multiply(new BigInteger(i+""));
			}
			System.out.println(number);
		}
	}
}

其他还有涉及到大数运算的还有一个例子,就是大数运算与进制转换的结合。

题目描述

将 M 进制的数 X 转换为 N 进制的数输出。
输入:
输入的第一行包括两个整数: M 和 N(2<=M,N<=36)。
下面的一行输入一个数 X, X 是 M 进制的数,现在要求你将 M 进制的数 X
转换成 N 进制的数输出。
输出:
输出 X 的 N 进制表示的数。
样例输入:
16 10
F
样例输出:
15
提示:
输入时字母部分为大写,输出时为小写, 并且有大数据。
来源:
2008年清华大学计算机研究生机试真题

采用java中的tostring也可以快速完成进制的转化。

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

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()){
			int M = scanner.nextInt();
			int N = scanner.nextInt();
			String number = new BigInteger(scanner.next(),M).toString(N);
			System.out.println(number);
		}
		scanner.close();
	}
}

再附一题大数进制转换

题目描述
对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘B为A的二进制逆序数。 例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。
输入描述:
一个1000位(即10^999)以内的十进制数。
输出描述:
输入的十进制数的二进制逆序数。
示例1
输入
复制
173
输出
复制
181

public static void main(String[] args){
    Scanner scanner = new Scanner(System.in);
    while(scanner.hasNext()){
        String b = new BigInteger(scanner.next(),10).toString(2);
        int len = b.length();
        String s="";
        for(int i=0;i<len;i++)
            s+= b.charAt(len-i-1);
        System.out.println(new BigInteger(s,2).toString(10));
    }
    scanner.close();
}

再附一题大数排序例子

题目描述
对N个长度最长可达到1000的数进行排序。
输入描述:
输入第一行为一个整数N,(1<=N<=100)。
接下来的N行每行有一个数,数的长度范围为1<=len<=1000。
每个数都是一个正数,并且保证不包含前缀零。
输出描述:
可能有多组测试数据,对于每组数据,将给出的N个数从小到大进行排序,输出排序后的结果,每个数占一行。
示例1
输入
复制
3
11111111111111111111111111111
2222222222222222222222222222222222
33333333
输出
复制
33333333
11111111111111111111111111111
2222222222222222222222222222222222

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

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            BigInteger[] buf = new BigInteger[n];
            //a.compareTo(BigInteger b)
            for(int i=0;i<n;i++) {
            	buf[i] = sc.nextBigInteger();
            }
            for(int i=0;i<n-1;i++) {
            	for(int j=0;j<n-i-1;j++) {
            		if(buf[j].compareTo(buf[j+1])==1) {
            			BigInteger tmp;
            			tmp = buf[j];
            			buf[j]=buf[j+1];
            			buf[j+1]=tmp;
            		}
            	}
            }
            for(int i=0;i<n;i++) {
            	System.out.println(buf[i]);
            }
            
        }
        sc.close();
    }
   
}

补充:
当涉及到求大整数的因子的时候,需要用到以下的求余函数

BigInteger BigInteger.mod(BigInteger)//方法取得正余数
BigInteger BigInteger.remainder(BigInteger)//方法取得余数,符号随原数
BigInteger[] BigInteger.divideAndRemainder(BigInteger)//方法取得整除商[0]和余数[1],余数同2.

题目描述
已知正整数k满足2<=k<=9,现给出长度最大为30位的十进制非负整数c,求所有能整除c的k.
输入描述:
若干个非负整数c,c的位数<=30
每行一个c
输出描述:
每一个c的结果占一行
若存在满足 c%k == 0 的k,输出所有这样的k,中间用空格隔开,最后一个k后面没有空格。
若没有这样的k则输出"none"。
注意整数溢出问题不要对-1进行计算
示例1
输入
复制
30
72
13
输出
复制
2 3 5 6
2 3 4 6 8 9
none

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

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            BigInteger c = sc.nextBigInteger();
            int cnt=0;
            for(int k=2;k<=9;k++){
                if(c.mod(new BigInteger(k+"")).toString().equals("0")){
                    cnt++;
                    System.out.print(k+" ");
                }
            }
            if(cnt==0)System.out.print("none");
            System.out.println();
            
        }
        sc.close();
    }
    
}

Java中BigInteger主要用来处理整型数据,对于浮点型的数据可以采用BigDecimal数据类型进行处理。以下不对BigDecimal展开,只举一个简单的例子:

题目描述
求2个浮点数相加的和 题目中输入输出中出现浮点数都有如下的形式: P1P2…Pi.Q1Q2…Qj 对于整数部分,P1P2…Pi是一个非负整数 对于小数部分,Qj不等于0
输入描述:
对于每组案例,每组测试数据占2行,分别是两个加数。
输出描述:
每组案例是n行,每组测试数据有一行输出是相应的和。
输出保证一定是一个小数部分不为0的浮点数
示例1
输入
复制
0.111111111111111111111111111111
0.111111111111111111111111111111
输出
复制
0.222222222222222222222222222222

import java.util.Scanner;
import java.math.BigDecimal;

public class Main{
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            BigDecimal a= sc.nextBigDecimal();
            BigDecimal b= sc.nextBigDecimal();
            System.out.println(a.add(b).toString());
            
        }
        
    }    
}

关于java大数类BigInteger中的一些基本操作方法可以参考这篇写的很详细的博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值