因为我感觉这两种题型都是对高精度的考察,都可以用数组代替整形进行数字运算,所以我把这两种题型放在一起了。
使用数组来表示一个大数,使用数组来进行乘法运算
这种解法关键要记住如何进行乘法运算主要是如何进位
设置一个数temp
,temp
等于当前位上的数a[j]
与乘数i
的乘积再加上上一位的进位jw
,这时很明显现在当前位上的数就是temp%10
,而下位数的进位就是temp/10
了,这个是解题的关键,在高精度加法运算中,进位也采用此种方法即可。还有就是为了确保数组能够容纳结果的长度,数组大小应设置的尽可能大,但从算法效率的角度,又不能太过于大,所以数组的大小应当适中
,我们此时选择的是2000作为数组大小。
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//收集进位的信息
int jw = 0;
//定义数组的大小及最大的位数
int max =4000;
int[] nums = new int[max];
nums[0] = 1;
int temp;
for(int i=2;i<=n;i++){
for(int j=0;j<max;j++){
//常用套路
temp = nums[j]*i+jw;
jw = temp / 10;
nums[j] = temp % 10;
}
}
max--;
while(nums[max]==0){
max--;
}
for(int i=max;i>=0;i--){
System.out.print(nums[i]);
}
}
}
Java里面有这样一种数据类型,是BigInteger
BigInteger类型的数字范围较Integer,Long类型的数字范围要大得多,它支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值而不会丢失任何信息。
而它的这种特性用在数据范围大的题目上正好合适。
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 bigint = BigInteger.valueOf(1);
for(int i=2;i<=n;i++){
//BigInteger我愿称之为yyds
bigint = bigint.multiply(BigInteger.valueOf(i));
}
System.out.println(bigint);
}
}
但是需要注意的是BigInteger在赋初值时要用BigInteger.valueOf()
创建BigInteger值,才能进行赋值,进行加乘运算时也要使用该数据类型自带的multiply或者add
函数
这个大数要自己输入所以在用数组来进行高精度加法运算的过程中,先要将输入的字符串转化成字符数组在将字符数组转化为数组运算
。
代码如下:
import java.util.Collection;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int temp;
int jw=0;
String[] add = new String[2];
for(int i=0;i<add.length;i++){
add[i] = sc.next();
}
//将字符串颠倒的方法
String addone = (String) new StringBuffer(add[0]).reverse().toString();
String addtwo = (String) new StringBuffer(add[1]).reverse().toString();
//将字符串转化为字符数组
char[] add1 = addone.toCharArray();
char[] add2 = addtwo.toCharArray();
//计算出那个字符数组长的那个的长度和短的那个的长度
int max = Math.max(add1.length, add2.length);
int min = Math.min(add1.length, add2.length);
int[] sum = new int[max+1];
//在长度为min之前两个数相加
for(int i=0;i<min;i++){
//数组进位计算的常用套路
//将字符数组转化为数组运算
temp = (int)(add1[i]-'0')+(int)(add2[i]-'0') + jw;
jw = temp / 10;
sum[i] = temp % 10;
}
//多出来的部分注意进位就行了,不需要相加
for(int i=min;i<max;i++){
if(add1.length>add2.length){
temp = (int)(add1[i]-'0') + jw;
}else{
temp = (int)(add2[i]-'0') + jw;
}
jw = temp / 10;
sum[i] = temp % 10;
}
//防止进位后比max还高一位,如果进位jw仍不为0,再进行一次进位
if(jw!=0){
sum[max]=jw;
}
while(sum[max]==0){
max--;
}
for(int i=max;i>=0;i--){
System.out.print(sum[i]);
}
}
}
直接使用BigInteger进行加法运算
这里注意一下BigInteger数据类型在输入数据是需要使用BigInteger bigint = sc.nextBigInteger();
这种形式即可
代码如下:
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger bigint1 = sc.nextBigInteger();
BigInteger bigint2 = sc.nextBigInteger();
System.out.println(bigint1.add(bigint2));
}
}
总结一下:两题虽然两种方法都写了一下,但是对于这两题的解法我都推荐使用第二种方法,首先第二种方法代码量少,逻辑简单,可以很好的节省时间,然后就是即然选择用Java来参加比赛,那Java里面的类和方法就尽可能的用上,可以很大程度上的节省时间。