题干——
Problem Description
|
Input
|
注:依最后两句的提示知,系统输入的数字不仅会超过int的最大值,连long也无法容纳!所以我们不能用传统的定义int或long再通过相加得出结果.
Output
|
法1:
分析:我们既然不能用纯数字来解决,我们可以通过将输入的各个数位改为字符常量然后一一存入数组,以便于后续两者相加.
⒈.先搭好整体框架,再输入字符串变量
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
String strA, strB;
int[] a = new int[1000];
int[] b = new int[1000];
strA = k.next();
strB = k.next();
⒉.对于strA和strB的数据进行一一提取(单个字符常量)并存入a[] 和b[]数组中
import java.util.Scanner;
public class Main{
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
String strA, strB;
int[] a = new int[1000];
int[] b = new int[1000];
char m, n;
int sum;
strA = k.next();
strB = k.next();
for (int i = 0; i < strA.length(); i++) {
m = strA.charAt(i);
a[i] = (int) m - (int) ('0');
}
for (int i = 0; i < strB.length(); i++) {
n = strB.charAt(i);
b[i] = (int) n - (int) ('0');
}
在对于字符串变量提取字符变量,再转换为整形数组时,可采取ASCII码的转换;用(int)强制转换符号将提取出来的char字符变量换为int(PS:注意(int)‘0’的单引号)
(☆☆☆)但是,必须注意一个问题,数组的第一个下标为0,而不是1,故必须写成诸如
for (int i = 0; i < strA.length(); i++)
的形式,即i=0对应a[0] ,第一个数组对应的下标一定为0!
⒊.我们接下来就是至关重要的相加,顾名思义,利用存储数组的思想就是巧妙地运用竖式求和的方式!但是我们不得不思考到一个问题,若两者数字长度不一致,在竖式求和时必然会存在问题,所以我们应当比较两者的数字长度大小.在这里我们可以采用<字符串变量>.length();提取长度.
if (strA.length() < strB.length()) {
sum = strB.length();
for (int i = strA.length() - 1; i >= 0; i--) {
a[i + sum - strA.length()] = a[i];
}
for (int i = 0; i < sum - strA.length(); i++) {
a[i] = 0;
}
}
else {
sum = strA.length();
for (int i = strB.length() - 1; i >= 0; i--) {
b[i + sum - strB.length()] = b[i];
}
for (int i = 0; i < sum - strB.length(); i++) {
b[i] = 0;
}
}
当比较出两者的相对大小后,由竖式的相加原理,我们应当在位数较小的数字前面补“0”使得两个数组长度一致,才能进行最终的计算.同时我们定义俩数组的最大值为sum,来实现定义补“0”位数的下标和后续的相加总位数.
⒋.我们可以通过定义t来实现进位功能:从最后一项逐渐往前,当每一次的数值和大于或等于10时应当减去10,而前一个项相加时会进1,而因为是两位相加绝不会出现进两位的情况,故只需t=1即可;当没有超过10时立即将t改为0.
int t=0;
for (int i=sum-1;i>=0;i--){
c[i]=a[i]+b[i]+t;
if (c[i]>=10){
c[i]=c[i]-10;
t=1;
}
else {
t=0;
}
⒌.最终实现输出时应当注意,因为c[i]是数组,我们应当逐一输出且不能换行;而在最后一个数组输出时必须换行两次
for (int i = 0; i < sum; i++) {
if (i < sum - 1) {
System.out.printf("%d", c[i]);
}
else {
System.out.printf("%d\n", c[i]);
System.out.println();
}
⒍.在整体思路通过代码实现后,我们再对细枝末节进行润色,如输入的次数,Case#: ,#的数字以及包含的空格等等!
最终成品为——
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
String strA, strB;
int[] a = new int[1000];
int[] b = new int[1000];
int[] c = new int[1000];
char m, n;
int sum, N, num;
N = k.nextInt();
num = N;//总次数
while (N > 0) {//输出N此
strA = k.next();
strB = k.next();
for (int i = 0; i < strA.length(); i++) {
m = strA.charAt(i);
a[i] = (int) m - (int) ('0');
}
for (int i = 0; i < strB.length(); i++) {//从i=0开始取第一个
n = strB.charAt(i);
b[i] = (int) n - (int) ('0');
}
if (strA.length() < strB.length()) {
sum = strB.length();//最大的字符串位数
for (int i = strA.length() - 1; i >= 0; i--) {
a[i + sum - strA.length()] = a[i];//前方补“0”
}
for (int i = 0; i < sum - strA.length(); i++) {
a[i] = 0;
}
} else {
sum = strA.length();
for (int i = strB.length() - 1; i >= 0; i--) {
b[i + sum - strB.length()] = b[i];
}
for (int i = 0; i < sum - strB.length(); i++) {
b[i] = 0;
}
}
int t = 0;
for (int i = sum - 1; i >= 0; i--) {
c[i] = a[i] + b[i] + t;
if (c[i] >= 10) {//实现进位
c[i] = c[i] - 10;
t = 1;
} else {
t = 0;
}
}
System.out.printf("Case %d:\n", num - N + 1);//输出Case#:且计算出#的大小
System.out.printf("%s + %s = ", strA, strB);
for (int i = 0; i < sum; i++) {
if (i < sum - 1) {
System.out.printf("%d", c[i]);//逐一输出
}
else {
System.out.printf("%d\n", c[i]);
System.out.println();//最后一位连换两行
}
N--;
}
}
}
}
法2:
当int甚至long无法满足取值范围时,我们可以通过引入超大整数类BigInteger来最大程度地满足取值范围。
同Scanner相同,BigInteger同样是来自于某头文件的,我们在顶部应当输入如下语句——
import java.math.BigInteger;
同理,我们能够通过下列语句来定义变量;
BigInteger sum;
能够通过下列语句来实现键盘输入.
BigInteger A = k.nextBigInteger();
BigInteger B = k.nextBigInteger();
对于BigInteger,我们有以下多种功能实现:
1.字符串转数字
String str="..."
BigInteger sum=new BigInteger(str);//先前未定义sum及其数据类型
或
BigInteger sum=new BigInteger("...");
2.运算
BigInteger a = new BigInteger("99999999999999999");
BigInteger b = new BigInteger("99999999999999999");
BigInteger add = a.add(b);// 加法
BigInteger subtract = a.subtract(b); // 减法
BigInteger multiply = a.multiply(b); // 乘法
BigInteger divide = a.divide(b); // 除法(*选学)
BigInteger mod = a.mod(b); // 取余(只返回正数)(*选学)
(*选学)BigInteger remainder = a.remainder(b); // 取余(正负数都有可能返回)
// 求商和余数
(*选学)BigInteger[] bigIntegers = a.divideAndRemainder(b); // 返回一个BigInteger数组,
// bigIntegers[0]是a/b的商,bigIntegersp[1]是a%b的余
(*选学)System.out.println(bigIntegers[0]+" "+bigIntegers[1]); // 1 0(商1,余0)
综上,最终成品为——
import java.util.Scanner;
import java.math.BigInteger;
public class Main1002_2 {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
String str,strA,strB;
int N;
BigInteger sum;
N = k.nextInt();
int num=N;
while(N>0) {
BigInteger A = k.nextBigInteger();
BigInteger B = k.nextBigInteger();
sum = A.add(B);
str = sum.toString();
strA = A.toString();
strB = B.toString();
System.out.println("Case "+(num-N+1)+":");
if (N != 1) {
System.out.println(strA+" + "+strB+" = "+str);
System.out.println();
}
else {
System.out.println(strA+" + "+strB+" = "+str);
}
N--;
}
}
}