算法模板(Java版)_非负整数的高精度运算
@ZZHow(ZZHow1024)
Java 中可使用大整数类(BigInteger)和大浮点数类(BigDecimal)处理高精度的运算。
非负整数的高精度加法
- 例题:AcWing 791. 高精度加法
数组实现
import java.util.Scanner;
import java.util.ArrayList;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);ArrayList<Integer> A = new ArrayList<>();ArrayList<Integer> B = new ArrayList<>();// 以字符串的形式读入,如:a = "123456";String a = scanner.next();String b = scanner.next();// 将字符串按位切割转存到可变数组中,如:A = [6, 5, 4, 3, 2, 1];for(int i = a.length() - 1; i >= 0; i--)A.add(a.charAt(i) - '0');for(int i = b.length() - 1; i >= 0; i--)B.add(b.charAt(i) - '0');ArrayList<Integer> C = add(A, B);for(int i = C.size() - 1; i >= 0; i--)System.out.print(C.get(i));}// C = A + Bpublic static ArrayList<Integer> add(ArrayList<Integer> A, ArrayList<Integer> B) {ArrayList<Integer> C = new ArrayList<>();// 进位int t = 0;for(int i = 0; i < A.size() || i < B.size(); i++) {if(i < A.size())t += A.get(i);if(i < B.size())t += B.get(i);C.add(t % 10);t /= 10;}if(t != 0)C.add(1);return C;}
}
大整数类实现
import java.util.Scanner;
import java.math.BigInteger;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigInteger a = scanner.nextBigInteger();BigInteger b = scanner.nextBigInteger();System.out.println(a.add(b));}
}
非负整数的高精度减法
- 例题:AcWing 791. 高精度加法
数组实现
import java.util.Scanner;
import java.util.ArrayList;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);ArrayList<Integer> A = new ArrayList<>();ArrayList<Integer> B = new ArrayList<>();// 以字符串的形式读入,如:a = "123456";String a = scanner.next();String b = scanner.next();// 将字符串按位切割转存到可变数组中,如:A = [6, 5, 4, 3, 2, 1];for(int i = a.length() - 1; i >= 0; i--)A.add(a.charAt(i) - '0');for(int i = b.length() - 1; i >= 0; i--)B.add(b.charAt(i) - '0');if(cmp(A, B)) {ArrayList<Integer> C = sub(A, B);for(int i = C.size() - 1; i >= 0; i--)System.out.print(C.get(i));} else {ArrayList<Integer> C = sub(B, A);System.out.print("-");for(int i = C.size() - 1; i >= 0; i--)System.out.print(C.get(i));}}// 判断 A 和 B 的大小(A >= B 返回 true,A < B 返回 false)public static boolean cmp(ArrayList<Integer> A, ArrayList<Integer> B) {if(A.size() != B.size())return A.size() > B.size();for(int i = A.size() - 1; i >= 0; i--)if(A.get(i) != B.get(i))return A.get(i) > B.get(i);return true;}// C = A - Bpublic static ArrayList<Integer> sub(ArrayList<Integer> A, ArrayList<Integer> B) {ArrayList<Integer> C = new ArrayList<Integer>();// 借位int t = 0;for(int i = 0; i < A.size(); i++) {t = A.get(i) - t;if(i < B.size())t -= B.get(i);C.add((t + 10) % 10);if(t < 0)t = 1;elset = 0;}// 去除无效0while(C.size() > 1 && C.get(C.size() - 1) == 0)C.remove(C.size() - 1);return C;}
}
大整数类实现
import java.util.Scanner;
import java.math.BigInteger;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigInteger a = scanner.nextBigInteger();BigInteger b = scanner.nextBigInteger();System.out.println(a.subtract(b));}
}
非负整数的高精度乘法
- 例题:AcWing 793. 高精度乘法
数组实现
import java.util.Scanner;
import java.util.ArrayList;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 以字符串的形式读入,如:a = "123456";String a = scanner.next();int b = scanner.nextInt();// 将字符串按位切割转存到可变数组中,如:A = [6, 5, 4, 3, 2, 1];ArrayList<Integer> A = new ArrayList<>();for (int i = a.length() - 1; i >= 0; i--)A.add(a.charAt(i) - '0');ArrayList<Integer> C = mul(A, b);for (int i = C.size() - 1; i >= 0; i--) {int out = C.get(i);System.out.print(out);}}// C = A * bpublic static ArrayList<Integer> mul(ArrayList<Integer> A, int b) {ArrayList<Integer> C = new ArrayList<>();// 进位int t = 0;for (int i = 0; i < A.size() || t != 0; i++) {if (i < A.size())t += A.get(i) * b;C.add(t % 10);t /= 10;}// 去除无效0while (C.size() > 1 && C.get(C.size() - 1) == 0)C.remove(C.size() - 1);return C;}
}
大整数类实现
import java.util.Scanner;
import java.math.BigInteger;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigInteger a = scanner.nextBigInteger();BigInteger b = scanner.nextBigInteger();System.out.println(a.multiply(b));}
}
非负整数的高精度除法
- 例题:AcWing 794. 高精度除法
数组实现
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 以字符串的形式读入,如:a = "123456";String a = scanner.next();int b = scanner.nextInt();// 将字符串按位切割转存到可变数组中,如:A = [6, 5, 4, 3, 2, 1];ArrayList<Integer> A = new ArrayList<>();for (int i = a.length() - 1; i >= 0; i--) {A.add(a.charAt(i) - '0');}AtomicInteger r = new AtomicInteger();ArrayList<Integer> C = div(A, b, r);for (int i = C.size() - 1; i >= 0; i--) {System.out.print(C.get(i));}System.out.println("\n" + r);}// A / b,商C余rpublic static ArrayList<Integer> div(ArrayList<Integer> A, int b, AtomicInteger r) {ArrayList<Integer> C = new ArrayList<>();// 余数r.set(0);for (int i = A.size() - 1; i >= 0; i--) {r.set(r.get() * 10 + A.get(i));C.add(r.get() / b);r.set(r.get() % b);}Collections.reverse(C);// 去除无效0while (C.size() > 1 && C.get(C.size() - 1) == 0)C.remove(C.size() - 1);return C;}
}
大整数类实现
import java.util.Scanner;
import java.math.BigInteger;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigInteger a = scanner.nextBigInteger();BigInteger b = scanner.nextBigInteger();System.out.println(a.divide(b));System.out.println(a.mod(b));}
}
补充 Java 大整数类的常用方法
基本运算
- 加:
a.add(b);
- 减:
a.subtract(b);
- 乘:
a.multiply(b);
- 除:
a.divide(b);
- 取模:
a.mod(b);
- 求余:
a.remainder(b);
- 幂:
a.pow(n);
- 取绝对值:
a.abs();
- 取相反数:
a.negate();
- 比较大小
比较大小
a.compareTo(b);
- 返回 1:大于
- 返回 0:等于
- 返回 -1:小于
常量
- 0:
BigInteger.ZERO;
- 1:
BigInteger.ONE;
- 10:
BigInteger.TEN;
类型转换
- 转换为二进制补码形式:
a.toByteArray();
- 转换为十进制字符串形式:
a.toString();
- 转换为 x 进制字符串形式:
a.toString(x);
- 转换为 int:
a.intValue();
- 转换为 long:
a.longValue();
- 转换为 flout:
a.floatValue();
- 转换为 double:
a.doubleValue();