版权声明:转载请注明博主地址 https://blog.csdn.net/weixin_43885417/article/details/86749996
在很多的算法题中,我们经常会遇到两个大数相加,相减,相乘,相除。那么,今天分享一下java如何实现大数的四则运算。
两个大数相加:
核心算法:
- 两个大数存入字符数组,再定义一个结果数组,长度为前面最大的数组长度 加 1,再定义一个进位变量,从右到左开始计算(个位开始)。
- 利用循环,遍历两个数组,实现两个数字相加。
- 中间需要判断一下,两个数相加是否大于9,如果大于,要进1。
- 最后循环输出结果数组。
下面看代码:
方法一(循环):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
System.out.println(add2(sca.next(), sca.next()));
sca.close();
}
public static String add2(String digit1, String digit2) {
String result = "";
char[] s1 = digit1.toCharArray();
char[] s2 = digit2.toCharArray();
char[] jg = new char[Math.max(s1.length, s2.length) + 1];// 结果数组比最常参数再长一位
int carry = 0; // 表示进位
for (int i = 0; i < jg.length; i++) {
char a1 = '0';
char a2 = '0';
if (s1.length - 1 - i >= 0) {
a1 = s1[s1.length - 1 - i];
}
if (s2.length - 1 - i >= 0) {
a2 = s2[s2.length - 1 - i];
}
char a = (char) (a1 + a2 - '0' + carry);
if (a > '9') {
carry = 1;
a = (char) (a - 10);
} else {
carry = 0;
}
jg[jg.length - 1 - i] = a;
}
for (int i = 0; i < jg.length; i++) {
if (i == 0 && jg[i] == '0') {
} else {
result += jg[i];
}
}
return result;
}
}
方法二(递归):
import java.util.Scanner;
public class Main {
static StringBuffer result = new StringBuffer();
static int maxLen = 0;
static int lenOne = 0;
static int lenTwo = 0;
static int carry = 0;
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
char [] data1 = sca.next().toCharArray();
char [] data2 = sca.next().toCharArray();
maxLen = Math.max(data1.length, data2.length) + 1;
lenOne = data1.length;
lenTwo = data2.length;
addBigInt(data1, data2, 0);
System.out.println(result.toString().replaceAll("^0*", ""));
sca.close();
}
public static void addBigInt(char [] num1, char [] num2, int iterate) {
if(iterate == maxLen) {
return ;
}
char tempOne = '0';
char tempTwo = '0';
int indexOne = lenOne - iterate - 1;
int indexTwo = lenTwo - iterate - 1;
if(indexOne >= 0) {
tempOne = num1[indexOne];
}
if(indexTwo >= 0) {
tempTwo = num2[indexTwo];
}
char temp = (char)(tempOne + tempTwo - '0' + carry);
if(temp > '9') {
carry = 1;
temp = (char)(temp - 10);
}else {
carry = 0;
}
result.insert(0,temp);
addBigInt(num1, num2, iterate + 1);
}
}
测试数据:
输入:
987654321987654321 987654321987654321
输出:
1975308643975308642
两个大数相减:
其实两个大数相减和相加差不多,只不过中间处理有点差别。
核心算法:
- 首先判断,用户输入的第一个大数和第二个大数的大小进行比较,如果第一个数字大,那么直接往下走,否则,交换两个数,并在输出结果前加 “-”。
- 计算两个数相减的时候,在保存每次相减的结果时,以前是减 ‘0’,现在要变成 加 ‘0’,再减去 去位变量carry。
- 当每次计算结果,小于 ‘0’ 时,相应的计算结果 要 + 10,carry = 1。
- 最后输出结果。
import java.util.Scanner;
public class bigNumReduce {
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
char [] dataOne = sca.next().toCharArray();
char [] dataTwo = sca.next().toCharArray();
char [] result = new char [Math.max(dataOne.length, dataTwo.length)];
if(dataOne.length < dataTwo.length
|| (dataOne[0] < dataTwo[0] && dataOne.length == dataTwo.length)) {
char [] tempData = dataOne;
dataOne = dataTwo;
dataTwo = tempData;
System.out.print("-");
}
int carry = 0;
int oneLen = dataOne.length;
int twoLen = dataTwo.length;
for(int i = 0; i < result.length; i++) {
char tempOne = '0';
char tempTwo = '0';
if(oneLen - 1 - i >= 0) {
tempOne = dataOne[oneLen - 1 - i];
}
if(twoLen - 1 - i >= 0) {
tempTwo = dataTwo[twoLen - 1 - i];
}
char temp = (char)(tempOne - tempTwo + '0' - carry);
if(temp < '0') {
temp = (char)(temp + 10);
carry = 1;
}else {
carry = 0;
}
result[result.length - 1 - i] = temp;
}
for(int i = 0; i < result.length; i++) {
if(result[i] != '0') {
System.out.print(result[i]);
}
}
sca.close();
}
}
两个大数相乘:
我们先学习一下,常见的两个数字相乘:
例如:
模拟一下计算的过程:
AB * CD = A* C(B * C + A* D) B* D ,从后到前满十进位。
12 * 82 = 1 * 8(2 * 8 + 1 * 2)2 * 2
12 * 82 = 8(18)4
从后到前满十进位
4不满十,不做任何处理。
18满十,进1,余8。
8变为9。
所以最后结果为:984
核心算法
- 首先定义两个存放数字的字符数组,然后定义一个存放结果的字符数组,长度为前两个数组长度之和(两个数相乘,得出的数的长度不可能超过原来两个数的长度之和)。
- 然后,再定义两个整型数组,用于存放转化的后的数字。
- 然后定义双层循环,用于模拟上述的数字计算,让第一个数组的每一个数分别乘以第二个数组中的数,并且把结果存放在下标为两个循环变量之和的位置。
- 再写一个循环,把计算的数进行,进位转化。
- 最后输出结果。
下面看代码:
import java.util.Scanner;
public class bigNumProduct {
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
char [] dataOne = sca.next().toCharArray();
char [] dataTwo = sca.next().toCharArray();
int lenOne = dataOne.length;
int lenTwo = dataTwo.length;
int [] numOne = new int [lenOne];
int [] numTwo = new int [lenTwo];
int [] result = new int [lenOne + lenTwo];
for(int i = 0; i < lenOne; i++) {
numOne[i] = dataOne[i] - '0';
}
for(int i = 0; i < lenTwo; i++) {
numTwo[i] = dataTwo[i] - '0';
}
for(int i = 0; i < lenOne; i++) {
for(int j = 0; j < lenTwo; j++) {
result[i + j] += numOne[i] * numTwo[j];
}
}
for(int i = result.length - 1; i > 0; i--) {
result[i - 1] += result[i] / 10;
result[i] = result[i] % 10;
}
for(int i = 0; i < result.length - 1; i++) {
System.out.print(result[i]);
}
sca.close();
}
}
测试数据:
输入:
72106547548473106236 982161082972751393
输出:
70820244829634538040848656466105986748