最近在一套资料上看到一个算法题,大致意思是超出int类型长度的数据该如何相加得出正确的结果。个人利用空闲时间,作了一简单的笔记,希望对刚接触Java的
同学能有所启发与帮助。代码方面暂时未考虑性能等问题,只做一个简单的思维逻辑的分享,技术大牛请绕道或者分享一下更为优质的做法,本人一定虚心接受。
1、测试的时候,是从控制台获取输入的,所以我们需要编写代码从控制台获取输入。这里使用最强大的Scanner处理控制台输入。因为我只是简单的分享下处理思路,
所以这里的代码大多代码都是写死的,预期输入是一行两列,输入完后按ENTER键表示输入完成,列之间用空格分隔(其他不符合的输入肯定会报错)。
例如: 123 1 (正确的输入)
a123 1 (错误的输入)
123,1 (错误的输入,其中“,”用其他非空格的符号代替的都是错误的输入)
/**
* 获取控制台输入
* @param args
*/
public static void getInputStr(String[] args) {
args = new String[1];
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
// 这里不做其他处理,简单的从控制台获取一行两列字符串,列中间用空格分割
// 例如:123 456
args[0] = scanner.nextLine().trim();
cumputer(args);
}
2、真正的数据逻辑方法。
(1)输入的两列的字符串的长度可能不一致,比如:123 1,此时为了后续方便计算,先将这两个字符串的长度处理一致。处理方法为:以最长的字符串的长度为准,
在最短的字符串的前边补充0.
(2)因为存在最高位进位的情况,所以在步骤(1)处理完后,还需要在两个字符串的最前边补充一个0,那么最终处理完后的每个字符串的长度为输入的最长的字符串的长度+1.
(3)遍历最终处理后的字符串,从字符串的最后的字符开始,每次将两个字符串对应位置的字符拿出来相加,之后的处理方式为正常的数学逻辑思维。
(4)因为我计算时是从输入字符串最高位开始的,那么相加处理后的结果刚好是反的,所以这里要反转处理。
(5)因为处理最高位进位的情况的时候,补充了一个0,但是当高位不进1的时候,这里会多出来一个0,所以这里对于这情况将这个0截取掉。如果不处理的,会存在:
输入:123 1,结果:0124的情况,这种情况是因为最高位不需要进位的原因导致。
/**
* 数据逻辑处理
* @param args
*/
public static void cumputer(String[] args) {
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
StringBuilder sb3 = new StringBuilder();
// 存放待计算的数据最前便补充一个0,用来处理最高位加起来如果进位的情况。
sb1.append(0);
sb2.append(0);
String[] str1 = new String[2];
str1 = args[0].split(" ");
// 获取输入的两个字符串中最长的那个字符的长度
int aa1 = Arrays.stream(str1).sorted().mapToInt(String::length).max().getAsInt();
// 计算最长的字符串和最短的字符的长度差
int aa2 = (aa1 - str1[0].length()) == 0 ? (aa1 - str1[1].length()) : (aa1 - str1[0].length());
/*
给最短字符串的前边补0,使得其长度和最长字符的长度一样
*/
if (aa1 > str1[0].length()) {
for (int i = 0; i < aa2; i++) {
sb1.append(0);
}
}else {
for (int i = 0; i < aa2; i++) {
sb2.append(0);
}
}
sb1.append(str1[0]);
sb2.append(str1[1]);
int sum = 0,a = 0,b = 0;
/*
此时,(aa1 + 1)才是每个字符串处理的最终的长度,计算逻辑也是按照该长度处理。
(aa1是未处理数据前,输入的最长的字符串的长度。+1是因为处理最高位进位的情况的时候,补充了一个0。)
处理逻辑:遍历最终处理后的字符串,从字符串的最后的字符开始,每次将两个字符串对应位置的字符拿出来相加,
之后的处理方式为正常的数学逻辑思维。
*/
for (int i = aa1 + 1; i > 0; i--) {
int x = Integer.valueOf(sb1.substring(i-1,i));
int y = Integer.valueOf(sb2.substring(i-1,i));
sum = x + y + a;
a = sum / 10; // 商,其实不是1就是0
b = sum % 10; // 余数
sb3.append(b);
}
// 因为我们计算时是从输入字符串最高位开始的,那么sb3的存放的结果刚好是反的,所以这里要反转处理。
String string = sb3.reverse().toString();
System.out.println("计算结果为:");
// 因为处理最高位进位的情况的时候,补充了一个0,但是当高位不进1的时候,这里会多出来一个0,所以这里对于这
// 情况将这个0截取掉。
if (string.startsWith("0")) {
string = string.substring(1,string.length());
System.out.println(string);
}else {
System.out.println(string);
}
}
3、测试结果: