1 /**
2 * Created by areful on 2019/11/133 */
4 public classCalcStringNumber {5 private static final String REG_EXP_NUMBER = "0|(-?[1-9]+[0-9]*)";6 private static final String REG_EXP_NON_NEGATIVE_NUMBER = "0|([1-9]+[0-9]*)";7
8 /**
9 * 带符号相加10 */
11 private staticString add(String s1, String s2) {12 assert s1.matches(REG_EXP_NUMBER) &&s2.matches(REG_EXP_NUMBER);13
14 boolean isPos1 = s1.charAt(0) != '-';15 boolean isPos2 = s2.charAt(0) != '-';16
17 if (isPos1 &&isPos2) {18 //都为非负数,直接无符号相加
19 returnaddPositive(s1, s2);20 } else if (!isPos1 && !isPos2) {21 //都为负数,无符号相加再取反
22 return '-' + addPositive(s1.substring(1), s2.substring(1));23 } else if(isPos1) {24 //1正,2负,比较字符串长度
25 if (s1.length() > s2.substring(1).length()) {26 //1比2长,正号
27 return subPositive(s1, s2.substring(1));28 } else if (s1.length() < s2.substring(1).length()) {29 //1比2短,负号
30 return '-' + subPositive(s1, s2.substring(1));31 } else{32 //长度相同,去掉符号比较字符串,根据比较结果做绝对值加减,并赋相应符号
33 int r = s1.compareTo(s2.substring(1));34 if (r > 0) return subPositive(s1, s2.substring(1));35 else if (r == 0) return "0";36 else return '-' + subPositive(s2.substring(1), s1);37 }38 } else{39 //1负,2正,比较字符串长度
40 if (s1.substring(1).length() >s2.length()) {41 //1比2长,负号
42 return '-' + subPositive(s1.substring(1), s2);43 } else if (s1.substring(1).length()
45 return subPositive(s2, s1.substring(1));46 } else{47 //长度相同,去掉符号比较字符串,根据比较结果做绝对值加减,并赋相应符号
48 int r = s1.substring(1).compareTo(s2);49 if (r > 0) return '-' + subPositive(s1.substring(1), s2);50 else if (r == 0) return "0";51 else return subPositive(s2, s1.substring(1));52 }53 }54 }55
56 /**
57 * 带符号相减58 */
59 private staticString sub(String s1, String s2) {60 assert s1.matches(REG_EXP_NUMBER) &&s2.matches(REG_EXP_NUMBER);61
62 boolean isPos1 = s1.charAt(0) != '-';63 boolean isPos2 = s2.charAt(0) != '-';64
65 if (isPos1 && !isPos2) {66 //1正,2负,去掉负号,做正整数相加
67 return addPositive(s1, s2.substring(1));68 } else if (!isPos1 &&isPos2) {69 //1负,2正,绝对值相加再取负号
70 return '-' + addPositive(s1.substring(1), s2);71 } else if(isPos1) {72 //均为正,比较字符串长度
73 if (s1.length() >s2.length()) {74 //1比2长,正号
75 returnsubPositive(s1, s2);76 } else if (s1.length()
78 return '-' +subPositive(s2, s1);79 } else{80 //长度相同,比较字符串,根据比较结果做绝对值加减,并赋相应符号
81 int r =s1.compareTo(s2);82 if (r > 0) returnsubPositive(s1, s2);83 else if (r == 0) return "0";84 else return '-' +subPositive(s2, s1);85 }86 } else{87 //均为负,比较字符串长度
88 if (s1.length() >s2.length()) {89 //1比2长,负号
90 return '-' + subPositive(s1.substring(1), s2.substring(1));91 } else if (s1.length()
93 return subPositive(s2.substring(1), s1.substring(1));94 } else{95 //长度相同,比较字符串,根据比较结果做绝对值加减,并赋相应符号
96 int r =s1.compareTo(s2);97 if (r > 0) return '-' + subPositive(s1.substring(1), s2.substring(1));98 else if (r == 0) return "0";99 else return subPositive(s1.substring(1), s2.substring(1));100 }101 }102 }103
104 /**
105 * 无符号相加106 */
107 private staticString addPositive(String s1, String s2) {108 assert s1.matches(REG_EXP_NON_NEGATIVE_NUMBER) &&s2.matches(REG_EXP_NON_NEGATIVE_NUMBER);109
110 int len1 =s1.length();111 int len2 =s2.length();112 int len =Math.max(len1, len2);113
114 //暂存计算结果
115 int[] result = new int[len];116 //进位符号,为1表示有进位
117 int carry = 0;118 for (int i = 0; i < len; i++) {119 int a1 = i < len1 ? s1.charAt(len1 - 1 - i) - '0' : 0;120 int a2 = i < len2 ? s2.charAt(len2 - 1 - i) - '0' : 0;121 //带进位相加
122 int a = a1 + a2 +carry;123 result[len - 1 - i] = a % 10;124 //判断当前计算是否产生进位
125 carry = a > 9 ? 1 : 0;126 }127
128 StringBuilder sb = newStringBuilder();129 //有进位则头部加1
130 if (carry == 1) sb.append('1');131 for (int i = 0; i < len; i++) sb.append(result[i]);132 returntrimZero(sb.toString());133 }134
135 /**
136 * 无符号相减137 */
138 private staticString subPositive(String s1, String s2) {139 assert s1.matches(REG_EXP_NON_NEGATIVE_NUMBER) &&s2.matches(REG_EXP_NON_NEGATIVE_NUMBER);140 if (s1.equals(s2)) return "0";141
142 int len1 =s1.length();143 int len2 =s2.length();144 int len =Math.max(len1, len2);145
146 //暂存计算结果
147 int[] result = new int[len];148 int carry = 0;149 for (int i = 0; i < len; i++) {150 int a1 = i < len1 ? s1.charAt(len1 - 1 - i) - '0' : 0;151 int a2 = i < len2 ? s2.charAt(len2 - 1 - i) - '0' : 0;152 //判断低一位计算是否产生借位,如有借位则减1
153 if (carry == 1) a1--;154 if (a1 >=a2) {155 //不需要借位,直接相减
156 carry = 0;157 result[len - 1 - i] = a1 -a2;158 } else{159 //需要借位,置借位标识并相减
160 carry = 1;161 result[len - 1 - i] = a1 + 10 -a2;162 }163 }164
165 StringBuilder sb = newStringBuilder();166 for (int i = 0; i < len; i++) sb.append(result[i]);167 returntrimZero(sb.toString());168 }169
170 /**
171 * 移除0开头的数字字符172 */
173 private staticString trimZero(String text) {174 StringBuilder sb = newStringBuilder();175 boolean needIgnore = true;176 for (charc : text.toCharArray()) {177 if (needIgnore && c == '0') continue;178 needIgnore = false;179 sb.append(c);180 }181 if (sb.length() == 0) sb.append('0');182 returnsb.toString();183 }184
185 public static voidmain(String[] args) {186 assert "0".equals(add("0", "0"));187 assert "-24".equals(add("-15", "-9"));188 assert "-6".equals(add("-15", "9"));189 assert "6".equals(add("15", "-9"));190 assert "24".equals(add("15", "9"));191 assert "2468".equals(add("1234", "1234"));192 assert "10470".equals(add("5235", "5235"));193 assert "0".equals(add("-1234", "1234"));194 assert "0".equals(add("1234", "-1234"));195 assert "-1".equals(add("1234", "-1235"));196 assert "1".equals(add("-1234", "1235"));197 assert "6".equals(add("15", "-9"));198 assert "-6".equals(add("-15", "9"));199 assert "24700000000000000000000000000000000000000000000000".equals(200 add("12350000000000000000000000000000000000000000000000", "12350000000000000000000000000000000000000000000000"));201
202 assert "0".equals(sub("0", "0"));203 assert "6".equals(sub("-9", "-15"));204 assert "-24".equals(sub("-9", "15"));205 assert "24".equals(sub("9", "-15"));206 assert "-6".equals(sub("9", "15"));207 assert "6".equals(sub("15", "9"));208 assert "-6".equals(sub("-15", "-9"));209 assert "-24".equals(sub("-15", "9"));210 assert "24".equals(sub("15", "-9"));211 assert "6".equals(sub("15", "9"));212 assert "-2469".equals(sub("-1234", "1235"));213 assert "-1".equals(sub("1234", "1235"));214 assert "0".equals(sub("1234", "1234"));215 assert "0".equals(sub("-1234", "-1234"));216 assert "-1234".equals(sub("0", "1234"));217 assert "1234".equals(sub("0", "-1234"));218 assert "1234".equals(sub("1234", "0"));219 assert "24700000000000000000000000000000000000000000000000".equals(220 sub("12350000000000000000000000000000000000000000000000", "-12350000000000000000000000000000000000000000000000"));221 }222 }