大数相减-4399笔试题

85 阅读1分钟

PS:不知道原题怎么给的,根据牛友爆料的大数相减,自己杜撰的,仅供参考,而且4399是人工阅卷,只能自己测试。

题目:给定String num1,String num2,要求进行大数相减。

其中num1和num2中每个字符都在数字0-9范围内,即不会出现num1 = "-123"的负号情况。且不会出现首位为0,即"01234"的情况。

以下是我的代码,如有错误欢迎讨论。 我没有用ACM模式读取输入,可自行替换。

思路:

  1. 两数相同返回0
  2. 两数不同就比较大小,统一转换为大数 - 小数,并记录是否为负数
  3. 具体相减时,如果diff < 0,说明要借位,变为diff+=10,carry = 1,否则不借位。carry = 0。并在res里插入结果
  4. 输出时要去除前导0
public class subtract {
    public static void main(String[] args) {
        //输入
        String num1 = "456";
        String num2 = "30";

        //处理大数相减
        //两数相同的情况
        if (num1.equals(num2)) {
            System.out.println(0);
            return;
        }
        //两数不同的情况
        StringBuilder res = new StringBuilder();
        //用逻辑值而非1和0来表明正负,更加清晰
        boolean isNegative = false;
        String largerNum, smallerNum;
        //比较两数大小,统一转换成大数 - 小数。俩数字的大小判断,不能单单比较长度,因为长度相等也有可能有正负。
        if (num1.length() < num2.length() || (num1.length() == num2.length() && num1.compareTo(num2) < 0)) {
            isNegative = true;
            largerNum = num2;
            smallerNum = num1;
        } else {
            largerNum = num1;
            smallerNum = num2;
        }

        int carry = 0;

        for (int i = largerNum.length() - 1, j = smallerNum.length() - 1; i >= 0; i--, j--) {
            int n1 = largerNum.charAt(i) - '0';
            //这里就解决了位数不一样就视为0的情况,如456-19,当n1处理到字符4的时候,n2由于 j < 0,视为0
            int n2 = j >= 0 ? smallerNum.charAt(j) - '0' : 0; 
            int diff = n1 - n2 - carry;
            if (diff < 0) {
                diff += 10;
                carry = 1;
            } else {
                carry = 0;
            }
            res.insert(0, diff);
        }
        //输出
        //去除前导0
        int index = 0;
        //注意不能超过res长度,否则会报错
        while (index < res.length() && res.charAt(index) == '0') {
            index++;
        }
        //负数就先输出个负号
        if (isNegative) System.out.print("-");
        //输出去除前导0后的结果
        System.out.println(res.substring(index));
    }
}