本身寫一個函數,求兩個大數相加之和【大廠面試乾貨】

前段時間,有幸參加了某釘的一個在線代碼測評,其中有一個算法題頗有意思,題目爲:git

//評測題目: 無// 大數加法// 實現一個函數,輸入兩個大整數字符串,計算兩數之和,用字符串表達。// 用例一://   輸入:"12345", "123"//   輸出:"12468"// 用例二://   輸入:"12345", "-123"//   輸出:"12222"// 用例三://   輸入:"12345", "-12345"//   輸出:"0"// 用例四://   輸入:"-12345", "123"//   輸出:"-12222"// 用例五://   輸入:"1111111111111111"(16位1), "2222222222222222" (16位2)//   輸出:"3333333333333333"(16位3)// 確保以上測試用例正確。

 

我初一看,這道題太簡單不過了,因而三下五除二,一分鐘就給他敲完了,實現以下:程序員

public class BigDigitalUtil {public static String digitialAdd(String a,String b){BigDecimal digital1 = BigDeciaml.valueOf(a);BigDecimal digital2 = BigDeciaml.valueOf(b);return digital1.add(digital2).toString();    }}public class TestBigDigitalAdd() {public static void main(String[] args) {String a = "12345";String b = "123";        System.out.println(BigDigitalUtil.digitialAdd(a,b));}}

 

這時候測評人跟我說,這麼寫不能說我錯,可是他的初衷是但願本身能實現這個算法,相似於本身實現BigDecimal的add方法。算法

 

因而,我開始從新審視這套題。首先是要求兩個大數相加,這個時候咱們就不能直接用int類型了,由於都知道int類型可表示的整數有限。其次又不能借助Java自帶的相似BigDecimal這樣的函數,怎麼辦呢?又默唸一遍存在即合理,既然有這道題的誕生,那麼必定能夠解。數組

 

這時候,我突然想到我我的自認爲「萬能」的String類型,咱們能夠把整數變成字符串啊,用字符串來表示大數,這樣就能夠實現大數相加了,整理了一下思路,主要要解決如下幾個問題:app

 

  1. 咱們小學就學過加減法,都是從個位數開始加減的,可是對於長度可能不一樣的字符串,咱們無法從第一位開始相加,只有從最後一位開始相加,因而,我要先將字符磚翻轉過來。函數

  2. 翻轉之後,要怎麼解決進位問題呢?還有可能和的位數也要進一的,這時候想到能夠把字符串短的那個前面高位都用」0」表示,這樣就方便一位一位的相加啦。測試

  3. 最後把得出來的值再翻轉過來就行了。ui

  4. 看到題目,若是其中有個大數是負數怎麼辦?既然前三步都能作出來,那負數是否是也能夠變成正數來計算呢?code

 

好了,既然思路理清楚了,那咱們廢話就很少說了,最後實現代碼以下:blog













package com.weiya.mazhichu.designpatterns.decorator;/*** <p class="detail">* 功能: 大數加法,實現一個函數,輸入兩個大整數字符串,計算兩數之和,用字符串表達。* </p>** @author Moore* @ClassName Big digital util.* @Version V1.0.* @date 2019.06.12 21:43:18*/public class BigDigitalUtil {//評測題目: 無// 大數加法// 實現一個函數,輸入兩個大整數字符串,計算兩數之和,用字符串表達。// 用例一://   輸入:"12345", "123"//   輸出:"12468"// 用例二://   輸入:"12345", "-123"//   輸出:"12222"// 用例三://   輸入:"12345", "-12345"//   輸出:"0"// 用例四://   輸入:"-12345", "123"//   輸出:"-12222"// 用例五://   輸入:"1111111111111111"(16位1), "2222222222222222" (16位2)//   輸出:"3333333333333333"(16位3)// 確保以上測試用例正確。/*** 兩個大數相加** @param a :* @param b :* @return string* @author Moore* @date 2019.06.12 23:43:42*/public static String bigDigitalAdd(String a, String b) {int aLength = a.length();int bLength = b.length();// 翻轉字符串成數組char[] aArray = new StringBuilder(a).reverse().toString().toCharArray();char[] bArray = new StringBuilder(b).reverse().toString().toCharArray();int MAX_LENGTH = aLength > bLength ? aLength : bLength;int[] newArray = new int[MAX_LENGTH + 1];// 按照數位對應相加,判斷當前位是否超過了當前數值的最大位數,若是是用0代替進行運算for (int i = 0; i < MAX_LENGTH + 1; i++) {int num1 = i < aLength ? (aArray[i] - '0') : 0;int num2 = i < bLength ? (bArray[i] - '0') : 0;newArray[i] = num1 + num2;}// 處理進位for (int i = 0; i < MAX_LENGTH + 1; i++) {if (newArray[i] > 10) {newArray[i + 1] += newArray[i] / 10;newArray[i] = newArray[i] % 10;}}StringBuilder result = new StringBuilder();//判斷是否有前置0,若是有忽略boolean hasZero = true;for (int i = MAX_LENGTH; i >= 0; i--) {if (newArray[i] == 0 && hasZero) {continue;} else {hasZero = false;}// 結果再翻轉過來result.append(newArray[i]);}return result.toString();}/*** 兩個大數相減(前提:a>b,求a-b)** @param a :* @param b :* @return string* @author Moore* @date 2019.06.12 23:43:42*/public static String bigDigitalSub(String a, String b) {char[] aArray = new StringBuilder(a).reverse().toString().toCharArray();char[] bArray = new StringBuilder(b).reverse().toString().toCharArray();int aLength = aArray.length;int bLength = bArray.length;int MAX_LENGTH = aLength > bLength ? aLength : bLength;int[] newArray = new int[MAX_LENGTH];for (int i = 0; i < MAX_LENGTH; i++) {int num1 = i < aLength ? (aArray[i] - '0') : 0;int num2 = i < bLength ? (bArray[i] - '0') : 0;newArray[i] = num1 - num2;}//若是結果中的某一位小於0,則向高位借位,而後將本位加10for (int i = 0; i < MAX_LENGTH; i++) {if (newArray[i] < 0) {newArray[i + 1] -= 1;newArray[i] += 10;}}StringBuilder result = new StringBuilder();boolean hasZero = false;for (int i = MAX_LENGTH - 1; i >= 0; i--) {if (hasZero == false && newArray[i] == 0) {continue;} else {hasZero = true;}result.append(newArray[i]);}return result.toString();}/*** 比較兩個大數的大小,a>b返回1,a小於b返回-1,a=b返回0** @param a :* @param b :* @return int* @author Moore* @date 2019.06.12 23:43:42*/public static int compareTo(String a, String b) {int aLength = a.length();int bLength = b.length();if (aLength > bLength) {return 1;} else if (aLength < bLength) {return -1;} else {int index = 0;while (true) {// 每一個位數比較大小if (a.charAt(index) > b.charAt(index)) {return 1;} else if (a.charAt(index) < b.charAt(index)) {return -1;} else {if (index == aLength - 1) {return 0;}index++;}}}}/*** 求兩個大整數之和(正數可爲負數)** @param a :* @param b :* @return* @author Moore* @date 2019.06.12 23:43:42*/public static String bigDigitalSum(String a, String b) {String result = null;//若是兩個大數都是負數if (a.charAt(0) == '-' && b.charAt(0) == '-') {a = a.substring(1);b = b.substring(1);result = bigDigitalAdd(a, b);result = "-" + result;}//若是兩個大數中,一個正數,一個負數else if (a.charAt(0) == '-' || b.charAt(0) == '-') {if (a.charAt(0) == '-') {a = a.substring(1);if (compareTo(a, b) == 1) {result = "-" + bigDigitalSub(a, b);} else if (compareTo(a, b) == -1) {result = bigDigitalSub(b, a);} else {result = "0";}} else {b = b.substring(1);if (compareTo(a, b) == 1) {result = bigDigitalSub(a, b);} else if (compareTo(a, b) == -1) {result = "-" + bigDigitalSub(b, a);} else {result = "0";}}}//兩個大數都是正數else {result = bigDigitalAdd(a, b);}return result;}public static void main(String[] args) {System.out.println(bigDigitalSum("12345","123"));System.out.println(bigDigitalSum("12345","-123"));System.out.println(bigDigitalSum("12345","-12345"));System.out.println(bigDigitalSum("-12345","123"));System.out.println(bigDigitalSum("1111111111111111","2222222222222222"));}}

 

查看一下運行結果:

 

是否是很棒棒噠,是否是要愛上本身了,可當我再次看到這題的時候,又發現了一個bug,題目要求輸入兩個大數,拜託,輸入輸入,Scanner scanner = new Scanner(System.in);就這樣被我吃了,唉,難怪最後我沒有過,真是活該!哈哈!

 

經過這個案例,只是想說,在咱們遇到一個需求的時候,必定要先理清楚需求和思路再開始寫代碼,要記住,咱們不要作一個機器程序員,而是要作一個有思想的程序員,互聯網時代萬事以結果爲導向,注重速度的同時更要保證你交付的每一行代碼都有質量,這樣咱們創造的產品才能更有生命力。

相關文章
相關標籤/搜索