您的位置 首页 java

一个一百亿的计算器的实现(java代码实现)

源地址:

网上一搜一大把,搜出来的结果几乎都是我很崇敬的张孝祥老师写的这道题的思路,甚至有的直接把原文copy paste过来,没有一个用代码实现了的。于是自己琢磨了下,这里发布出来。虽然标题是一百亿,但实现结果可用于任意大整数。

直接上代码。这里只实现了大整数相加。有了这个,不难实现减、乘等其他操作。代码复制粘帖即可运行。

MyBigInteger.java

  1. import java.util.ArrayList;
  2. import java.util.regex.Matcher;
  3. import java.util.regex. Pattern ;
  4. /**
  5. * Created by Rocky on 14-3-26.
  6. */
  7. public class MyBigInteger {
  8. private char sign = ‘0’; // 0 表示正数 – 表示负数
  9. private byte[] data;
  10. public MyBigInteger() {
  11. this.data = “0”.get Byte s();
  12. }
  13. public MyBigInteger(String value) throws Exception {
  14. //正则表达式,输入 字符串 要求以 零个或一个 – 开头,其余都是数字
  15. Pattern pattern = Pattern.compile(“^-?\d+$”);
  16. if (value == null || value.length() <= 0) {
  17. value = “0”;
  18. }
  19. Matcher matcher = pattern.matcher(value);
  20. if (!matcher.find()) {
  21. throw new Exception(“the value is not a number string :” + value);
  22. }
  23. //获取字符串的第一个字符
  24. char firstChar = value.charAt(0);
  25. //data应该保存的是第一个非0数字后的字符串
  26. if (firstChar == ‘-‘) { //说明输入的是个负数
  27. if (value.length() >=2) {
  28. sign = firstChar;
  29. value = value.substring(1);
  30. value = getTemp(value); //得到value中第一个非0后的子字符串。
  31. }
  32. } else {
  33. value = getTemp(value);
  34. }
  35. this.data = value.getBytes();
  36. }
  37. /**
  38. * 得到一个字符串第一个非0后的字符串,如果没有找到,则返回 “0” 。如:00003435534,则返回3435534
  39. * @return
  40. */
  41. private String getTemp(String value){
  42. Pattern pattern = Pattern.compile(“[^0]{1}”);
  43. Matcher matcher = pattern.matcher(value);
  44. if (matcher.find()) {
  45. value = value.substring(matcher.start());
  46. } else {
  47. value = “0”;
  48. }
  49. return value;
  50. }
  51. public MyBigInteger add(MyBigInteger other) {
  52. MyBigInteger result = new MyBigInteger();
  53. int thisLength = this.data.length;
  54. int otherLength = other.data.length;
  55. int shorterLength = thisLength > otherLength ? otherLength : thisLength;
  56. ArrayList<Byte> resultData = new ArrayList<Byte>();
  57. int flag = 0; //表示相加时的 进位,或相减时的 借位
  58. int i = thisLength – 1;
  59. int j = otherLength – 1;
  60. int k = shorterLength;
  61. //两个数的符号相同
  62. if (other.sign == this.sign) {
  63. //从两个整数的个位开始依次相加
  64. while (k > 0) {
  65. Integer temp = new Integer(new String(new byte[]{this.data[i]})) + new Integer(new String(new byte[]{other.data[j]})) + flag;
  66. flag = temp / 10; //相加结果超过10时的进位。没有超过10,进位为 0
  67. resultData.add(0, ((temp % 10) + “”).getBytes()[0]); //把相加结果保存起来
  68. k–;
  69. i–;
  70. j–;
  71. }
  72. //把多出的位加入到结果中
  73. if (i == -1) {
  74. while (j >= 0) {
  75. Integer temp = new Integer(new String(new byte[]{other.data[j]})) + flag;
  76. flag = temp / 10;
  77. resultData.add(0, ((temp % 10) + “”).getBytes()[0]);
  78. j–;
  79. }
  80. } else if (j == -1) {
  81. while (i >= 0) {
  82. Integer temp = new Integer(new String(new byte[]{this.data[i]})) + flag;
  83. flag = temp / 10;
  84. resultData.add(0, ((temp % 10) + “”).getBytes()[0]);
  85. i–;
  86. }
  87. }
  88. //最后把flag加进结果中
  89. if (flag != 0) {
  90. for (byte by : (flag + “”).getBytes()) {
  91. resultData.add(0, by);
  92. }
  93. }
  94. result.sign = other.sign;
  95. } else { //符号不同
  96. if (thisLength > otherLength) { //说明this表示的整数绝对值大,所以最终结果的符号为this的符号
  97. result.sign = this.sign;
  98. resultData = subtract(this.data, other.data); //执行减法
  99. } else if (thisLength < otherLength) { //other表示的整数绝对值大,所以最终结果的符号为other的符号
  100. result.sign = other.sign;
  101. resultData = subtract(other.data, this.data);
  102. } else { //如果两个数据的位数相同
  103. Integer thisInt = 0;
  104. Integer otherInt = 0;
  105. //从第一位开始比较,直到两者不相等
  106. for (int n = 0; n < thisLength; n++) {
  107. thisInt = new Integer(new String(new byte[]{this.data[n]}));
  108. otherInt = new Integer(new String(new byte[]{other.data[n]}));
  109. if (!thisInt.equals(otherInt)) { //注意这里要使用equals方法,因为这里需要比较的是两者的内容
  110. break;
  111. }
  112. }
  113. //如果this的绝对值大
  114. if (thisInt > otherInt) {
  115. result.sign = this.sign;
  116. resultData = subtract(this.data, other.data);
  117. } else {
  118. result.sign = other.sign;
  119. resultData = subtract(other.data, this.data);
  120. }
  121. }
  122. }
  123. result.data = new byte[resultData.size()];
  124. for (int m = 0; m < resultData.size(); m++) {
  125. result.data[m] = resultData.get(m);
  126. }
  127. return result;
  128. }
  129. private ArrayList<Byte> subtract(byte[] larger, byte[] smaller) {
  130. ArrayList<Byte> resultData = new ArrayList<Byte>();
  131. int flag = 0;
  132. int i = smaller.length – 1;
  133. int j = larger.length – 1;
  134. int k = smaller.length;
  135. while (k > 0) {
  136. Integer temp = new Integer(new String(new byte[]{larger[j]})) + flag – new Integer(new String(new byte[]{smaller[i]}));
  137. if (temp < 0) { //如果相减结果小于0,说明需要借位,则把flag置为 -1,以便下一位减去
  138. flag = -1;
  139. temp += 10;
  140. } else { //如果大于零,需要把flag置为 0.不要忘记了
  141. flag = 0;
  142. }
  143. resultData.add(0, (temp + “”).getBytes()[0]);
  144. j–;
  145. i–;
  146. k–;
  147. }
  148. //下面的代码就不写注释了
  149. while (j >= 0) {
  150. Integer temp = new Integer(new String(new byte[]{larger[j]})) + flag;
  151. if (temp < 0) {
  152. flag = -1;
  153. temp += 10;
  154. } else {
  155. flag = 0;
  156. }
  157. resultData.add(0, (temp + “”).getBytes()[0]);
  158. j–;
  159. }
  160. return resultData;
  161. }
  162. @Override
  163. public String toString() {
  164. String str = new String(this.data);
  165. str = getTemp(str);
  166. if (sign == ‘-‘ && str !=”0″) {
  167. str = sign + str;
  168. }
  169. return str;
  170. }
  171. }

MyBigIntegerTest.java

  1. import junit.framework.TestCase;
  2. import java.math.BigInteger;
  3. /**
  4. * Created by Rocky on 14-3-26.
  5. */
  6. public class MyBigIntegerTest extends TestCase {
  7. public void test1() throws Exception {
  8. String a1 = “-5453450543044355356576980545345054545453453454344435353254545345054304435535657698087756454543454345454534534543444353532545453450543044355356454543454354353450136546534534545345345054353450136546534534545345345043044355356576980657698087756454543454354353450136546534534545345345054353450136546534534545345345043044355356576980877564545434543543534501877564545434543543534501”;
  9. String b1 = “4545453453454344435353254545345054304435535657698087756454543454354345454534534543444353532545453450543044355356576980877564545434545454534534564545434543543534501365465345345453453450543534501365465345345453453450430443553565769804344435353254545345054304435535657698087756454543454354353450136546534534545345345043543534501365465345345453453450534501365465345345453453450”;
  10. MyBigInteger a = new MyBigInteger(a1);
  11. MyBigInteger b = new MyBigInteger(b1);
  12. MyBigInteger c = a.add(b);
  13. System.out.println(c);
  14. BigInteger a2 = new BigInteger(a1);
  15. BigInteger b2 = new BigInteger(b1);
  16. BigInteger c2 = a2.add(b2);
  17. System.out.println(c2);
  18. System.out.println(c2.toString().equals(c.toString()));
  19. }

文章来源:智云一二三科技

文章标题:一个一百亿的计算器的实现(java代码实现)

文章地址:https://www.zhihuclub.com/187118.shtml

关于作者: 智云科技

热门文章

发表回复

您的电子邮箱地址不会被公开。

网站地图