zoukankan      html  css  js  c++  java
  • Java实现字符串形式大数相加

    思路还是比较清晰,用自定义类型保存输入的数据,逐位相加/相减,需要处理好借位及符号。

    总共两个类,一个自定义类型Int,一个AddUtil封装加法操作。附带测试类AddUtilTest。代码如下:

    Int.java:

    package cn.areful;
    
    /**
     * Created by areful, 2020/05/02
     */
    public class Int {
        //符号
        public boolean isPositive = true;
        //有效长度
        public int len;
        //各位位数
        public int[] digits;
    
        public Int(boolean flag, int len) {
            isPositive = flag;
            this.len = len;
            digits = new int[len];
        }
    
        public Int(String s) {
            checkValid(s);
    
            char fst = s.charAt(0);
            String tmp;
            if (fst == '+' || fst == '-') {
                isPositive = fst != '-';
                len = s.length() - 1;
                tmp = s.substring(1);
            } else {
                len = s.length();
                tmp = s;
            }
    
            digits = new int[len];
    
            //各位数逆序存放
            for (int i = 0; i < len; i++) {
                digits[i] = tmp.charAt(len - 1 - i) - '0';
            }
        }
    
        //检查输入是否合法.
        private static void checkValid(String s) {
            if (!s.matches("(0|([+-]?[1-9]+[0-9]*))")) {
                throw new RuntimeException("Invalid String number: " + s);
            }
        }
    
        //去除结果之前多余的0
        public Int stripZero() {
            for (int i = len - 1; i >= 0; i--) {
                if (digits[i] != 0) {
                    break;
                }
                len--;
            }
            int[] tmp = new int[len];
            if (len >= 0) {
                System.arraycopy(digits, 0, tmp, 0, len);
            }
            digits = tmp;
            return this;
        }
    
        @Override
        public String toString() {
            //逆序输出
            StringBuilder sb = new StringBuilder();
            for (int i = len - 1; i >= 0; i--) {
                sb.append(digits[i]);
            }
            return !isPositive ? "-" + sb : sb.toString();
        }
    }
    

      AddUtil.java:

    package cn.areful;
    
    /**
     * Created by areful, 2020/05/02
     */
    public class AddUtil {
    
        public static Int add(Int i1, Int i2) {
            if (i1.isPositive && i2.isPositive) {
                //都为正数,各位相加,符号为正
                return addPositive(i1, i2);
            } else if (!i1.isPositive && !i2.isPositive) {
                //都为负数,各位相加,符号为负
                Int r = addPositive(i1, i2);
                r.isPositive = false;
                return r;
            }
    
            //以下为一正一负
            if (i1.len > i2.len) {
                //第一个数较长,符号取第一个数符号,各位相减
                return subPositive(i1, i2);
            } else if (i1.len < i2.len) {
                //第二个数较长,符号取第二个数符号,各位相减
                return subPositive(i2, i1);
            }
    
            //两数长度相等,逐位判断大小
            for (int i = i1.len - 1; i >= 0; i--) {
                int d1 = i1.digits[i];
                int d2 = i2.digits[i];
                //想等则比较下一位
                if (d1 == d2) continue;
                if (d1 > d2) {
                    //第一个数绝对值较大,取第一个数符号,各位相减
                    return subPositive(i1, i2);
                } else {
                    //第二个数绝对值较大,符号取第二个数符号,各位相减
                    return subPositive(i2, i1);
                }
            }
    
            //两数相等,返回0
            return new Int("0");
        }
    
        //两个正整数相加
        private static Int addPositive(Int i1, Int i2) {
            int maxLen = Math.max(i1.len, i2.len);
            Int r = new Int(true, maxLen + 1);
            int carry = 0;
            for (int i = 0; i < maxLen; i++) {
                int c1 = i >= i1.len ? 0 : i1.digits[i];
                int c2 = i >= i2.len ? 0 : i2.digits[i];
                int c = c1 + c2 + carry;
                carry = c > 9 ? 1 : 0;
                r.digits[i] = c % 10;
            }
            if (carry == 1) {
                r.digits[maxLen] = 1;
                r.len = maxLen + 1;
            } else {
                r.len = maxLen;
            }
            return r;
        }
    
        //两个正整数相减,第一个数要大于第二个数
        private static Int subPositive(Int i1, Int i2) {
            Int r = new Int(i1.isPositive, i1.len);
            int carry = 0;
            for (int i = 0; i < i1.len; i++) {
                int c1 = i1.digits[i] + carry;
                int c2 = i >= i2.len ? 0 : i2.digits[i];
                if (c1 < c2) {
                    carry = -1;
                    c1 += 10;
                } else {
                    carry = 0;
                }
                int c = c1 - c2;
                r.digits[i] = c % 10;
            }
    
            return r.stripZero();
        }
    
    }
    

      

      AddUtilTest:

    package cn.areful;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
     * Created by areful, 2020/05/02
     */
    public class AddUtilTest {
        @Test
        public void testPositiveAdd() {
            Assert.assertEquals(AddUtil.add(new Int("1234"), new Int("1234")).toString(), "2468");
            Assert.assertEquals(AddUtil.add(new Int("456"), new Int("789")).toString(), "1245");
            Assert.assertEquals(AddUtil.add(new Int("0"), new Int("1000")).toString(), "1000");
        }
    
        @Test
        public void testNegativeAdd() {
            Assert.assertEquals(AddUtil.add(new Int("-1234"), new Int("-1234")).toString(), "-2468");
            Assert.assertEquals(AddUtil.add(new Int("-150"), new Int("-1550")).toString(), "-1700");
        }
    
        @Test
        public void testFixedAdd() {
            Assert.assertEquals(AddUtil.add(new Int("1234"), new Int("-1234")).toString(), "0");
            Assert.assertEquals(AddUtil.add(new Int("1500"), new Int("-155")).toString(), "1345");
            Assert.assertEquals(AddUtil.add(new Int("-150"), new Int("1550")).toString(), "1400");
            Assert.assertEquals(AddUtil.add(new Int("0"), new Int("0")).toString(), "0");
            Assert.assertEquals(AddUtil.add(new Int("0"), new Int("-1234")).toString(), "-1234");
            Assert.assertEquals(AddUtil.add(new Int("-1234"), new Int("0")).toString(), "-1234");
        }
    }
    

      

  • 相关阅读:
    转载 初学者必看——最简单最清晰的Struts2项目搭建流程
    五种常见设计模式
    第二则java读取excel文件代码
    使用Maven运行Java main的3种方式使用Maven运行Java main的3种方式
    C++模式学习------策略模式
    C++模式学习------工厂模式
    人生辣么多的谎言,没必要一个个试一下
    常用函数说明
    python 查看与更换工作目录
    unix常用命令记录
  • 原文地址:https://www.cnblogs.com/areful/p/12818887.html
Copyright © 2011-2022 走看看