【JAVA】(vip)蓝桥杯试题 基础练习 高精度算法 BASIC-29 JAVA
目录
试题 基础练习 高精度加法
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
算法描述
由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
最后将C输出即可。
输入格式
输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
输出一行,表示a + b的值。
样例输入
20100122201001221234567890
2010012220100122
样例输出
20100122203011233454668012
要点
-
三目算法
-
JAVA中遍历字符串中字符的方法
-
JAVA为什么不建议在for循环中使用"+"进行字符串拼接,而是建议使用StringBuilder 的 append 方法?idea提示string concatenation ‘+=’in loop
JAVA为什么不建议在for循环中使用"+"进行字符串拼接,而是建议使用StringBuilder 的 append 方法?idea提示string concatenation ‘+=’in loop
-
考虑几个特殊值
-
999+999
- 999+9999
解题思路
总体上我都是按照题目给出的解题思路做的,具体实现思路有两种,一种是比较A数组和B数组的长度(也就是a字符串和b字符串的长度),然后按长度分阶段进行处理,另一种直接将比较短的数组变得和长的数组一样长度,这样就不用分阶段了
这道题的解法其实题目中的算法描述已经说的很清楚了
算法描述
由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
最后将C输出即可。
思路一:比较A、B数组长度大小,分阶段处理
代码
import java.util.ArrayList; import java.util.Scanner; public class HighPrecisionAddition4 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String a = sc.next(); String b = sc.next(); sc.close(); int[] A = reverse(a); int[] B = reverse(b); // System.out.println(Arrays.toString(A)); // System.out.println(Arrays.toString(B)); ArrayList C = add(A, B); // System.out.println(C); for (int i = C.size() - 1; i >= 0; i--) { System.out.print(C.get(i) + ""); } } public static int[] reverse(String a) { char[] tmpA = a.toCharArray(); int[] A = new int[a.length()]; int index = 0; for (int i = a.length() - 1; i >= 0; i--) { A[index++] = tmpA[i] - '0'; } return A; } public static ArrayList add(int[] A, int[] B) { int min; int max; boolean flag = true; //true为表示A的长度大于B的长度 if (A.length < B.length) { min = A.length; max = B.length; flag = false; } else if (A.length > B.length) { min = B.length; max = A.length; } else { min = max = A.length; } ArrayList<Integer> C = new ArrayList<Integer>(); int r = 0; //A和B长度相同时进行的运算 for (int i = 0; i < min; i++) { C.add((A[i] + B[i] + r) % 10); if (A[i] + B[i] + r < 10) { r = 0; } else { r = 1; } } //A和B长度相同,但是有999+999这种情况,会导致C长度不等于A和B的长度 if (r == 1 && min == max) { C.add(1); } //当A和B长度不一致时,我们已经进行过长度一致部分的运算,现在进行剩余的 if (min != max) { for (int i = min; i < max; i++) { C.add((r + (flag ? A[i] : B[i])) % 10); if ((r + (flag ? A[i] : B[i])) < 10) { r = 0; } else { r = 1; //可能会出现,999+9999这种情况。也是计算最后一位时,它又进位了,导致C长度变长 if (i == max - 1) { C.add(1); } } } } return C; } }
思路二:将较短的数组的长度变得和较长数组的长度一样
代码
import java.util.ArrayList; import java.util.Scanner; public class HighPrecisionAddition5 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String a = sc.next(); String b = sc.next(); sc.close(); int max = Math.max(a.length(), b.length()); int[] A = reverse(a, max); int[] B = reverse(b, max); // System.out.println(Arrays.toString(A)); // System.out.println(Arrays.toString(B)); ArrayList C = add(A, B); // System.out.println(C); for (int i = C.size() - 1; i >= 0; i--) { System.out.print(C.get(i) + ""); } } public static int[] reverse(String a, int max) { char[] tmpA = a.toCharArray(); int[] A = new int[max]; int index = 0; for (int i = a.length() - 1; i >= 0; i--) { A[index++] = tmpA[i] - '0'; } return A; } public static ArrayList add(int[] A, int[] B) { ArrayList<Integer> C = new ArrayList<Integer>(); int r = 0; //A和B长度相同时进行的运算 for (int i = 0; i < A.length; i++) { C.add((A[i] + B[i] + r) % 10); if (A[i] + B[i] + r < 10) { r = 0; } else { r = 1; } } //A和B长度相同,但是有999+999这种情况,会导致C长度不等于A和B的长度 if (r == 1) { C.add(1); } /*//当A和B长度不一致时,我们已经进行过长度一致部分的运算,现在进行剩余的 if (min != max) { for (int i = min; i < max; i++) { C.add((r + (flag ? A[i] : B[i])) % 10); if ((r + (flag ? A[i] : B[i])) < 10) { r = 0; } else { r = 1; //可能会出现,999+9999这种情况。也是计算最后一位时,它又进位了,导致C长度变长 if (i == max - 1) { C.add(1); } } } }*/ return C; } }爱做梦的鱼 原创文章 169获赞 1083访问量 7万+ 关注 私信
- 蓝桥杯试题集JAVA 基础练习 Basic-6 杨辉三角形
- 蓝桥杯 基础练习VIP 龟兔赛跑预测(java)
- 蓝桥杯 基础练习VIP 矩形面积交(java)
- [蓝桥杯][基础练习VIP]时间转换--java实现
- 蓝桥杯试题 JAVA 基础练习 数列排序
- 蓝桥杯 [基础练习VIP] FJ的字符串(Java解题)
- 蓝桥杯 基础练习VIP 时间转换(Java解题)
- 蓝桥杯 基础练习VIP 分解质因数(Java解题)
- 蓝桥杯vip基础练习 BASIC-28 Huffman树
- java:蓝桥杯试题 基础练习 龟兔赛跑预测
- 蓝桥杯 basic19试题 基础练习 完美的代价
- “蓝桥杯”练习系统 VIP试题 基础练习 阶乘计算
- [蓝桥杯][基础练习VIP]报时助手(Java解题)
- 蓝桥杯 基础练习VIP 龟兔赛跑预测(Java解题)
- 蓝桥杯 BASIC-29 基础练习 高精度加法
- 蓝桥杯 BASIC-19 基础练习 完美的代价 Java版
- 蓝桥杯 基础练习VIP 字符串对比(Java解题)
- [蓝桥杯][基础练习VIP]FJ的字符串--java实现
- 蓝桥杯试题 JAVA 基础练习 字母图形
- Java:蓝桥杯试题 基础练习 芯片测试