超长整数的减法实现

场景

当参加运算的数字是超过long型长度的数据,以至于只能用string字符串来存储,这时候加减乘除的运算已经不能用了。

对于这种问题Java提供了一个BigInteger类,可以用来存储,并有对应的加减乘除的方法,要求两个操作数都必须是BIgInteger型。可以解决问题。

这里从模拟计算机的内部实现解读来解决问题。

这个时候就可以像小时候列竖式来计算一样,一位一位的计算,或进位或借位,模拟计算的过程。将整个的计算拆解成一个个小的计算过程。

减法

减法需要判断两个数的大小和正负,大小可以通过长度和对应位的大小来比较,长度不同,长的 数字大,相同长度,对应位比较,第一次出现较大的数是大的。则用他的符号。同时,负数-正数可以当做加法来算。流程同上,只不过有符号的判断,这里不考虑。

因操作有点麻烦,这里默认是全正数且大数减小数

思路是

  1. 将把整数倒序存储,整数的个位存于数组0下标位置,最高位存于数组长度-1下标位置。之所以倒序存储,更加符合我们从左到右访问数组的习惯。
  2. 创建结果数组,结果数组的最大长度是较大整数的位数,不需要考虑加一的情况(负-正不考虑)。
  3. 遍历两个数组,从左到右按照对应下标把元素两两相减,够减直接在当前数组位置保存(当前数组位置的值 += 计算后的值),不够减按10减,借一位,第一个数字下一位的值减一。
  4. 把Result数组的全部元素再次逆序,若有0,去掉首位,0,就是最终结果。

代码实现

public class BigNumberSub {
    public static String bigNumberSub(String bigNumberA, String bigNumberB) {

        //1.把两个大整数用数组逆序存储
        char[] charsA = new StringBuffer(bigNumberA).reverse().toString().toCharArray();
        char[] charsB = new StringBuffer(bigNumberB).reverse().toString().toCharArray();

        //2.构建result数组,数组长度等于较大整数位数+1
        int maxLength = charsA.length > charsB.length ? charsA.length : charsB.length;
        int[] result = new int[maxLength + 1];
        //3.遍历数组,按位相减
        int[] need = new int[maxLength + 2];//判断是否需要借位
        for (int i = 0; i < result.length; i++) {
            int temp = 0;
            int a=0,b=0;
            if (i < charsA.length) {
                if(need[i]==1)
                    a= charsA[i] - '0'-1;
                a= charsA[i] - '0';
            }
            if (i < charsB.length) {
                b= charsB[i] - '0';
            }

        //判断是否借位
            if (a<b) {
                temp = a+10-b;
                need[i+1]=1;
            }else
                temp=a-b;
            result[i] = temp;
        }

       //4.把result数组再次逆序并转成String
        StringBuilder sb = new StringBuilder();
        boolean flag = true;
        for (int i = result.length - 1; i >= 0; i--) {
            //判断最后一位是否发生了进位
            if (result[i] == 0 && flag) {
                flag = false;
                continue;
            }

            sb.append(result[i]);
        }
        return sb.toString();
    }

    public static void main(String[] args)
    {
        System.out.println(bigNumberSub("222222222", "1111"));
    }
}

在这里插入图片描述
其他三则运算请看超长整数的四则运算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值