源地址:http://blog.csdn.net/wilsonpeng3/article/details/22441009
網上一搜一大把,搜出來的結果幾乎都是我很崇敬的張孝祥老師寫的這道題的思路,甚至有的直接把原文copy paste過來,沒有一個用代碼實現了的。於是自己琢磨了下,這裏發佈出來。雖然標題是一百億,但實現結果可用於任意大整數。
直接上代碼。這裏只實現了大整數相加。有了這個,不難實現減、乘等其他操作。代碼複製粘帖即可運行。
MyBigInteger.java
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Rocky on 14-3-26.
*/
public class MyBigInteger {
private char sign = '0'; // 0 表示正數 - 表示負數
private byte[] data;
public MyBigInteger() {
this.data = "0".getBytes();
}
public MyBigInteger(String value) throws Exception {
//正則表達式,輸入字符串要求以 零個或一個 - 開頭,其餘都是數字
Pattern pattern = Pattern.compile("^-?\\d+$");
if (value == null || value.length() <= 0) {
value = "0";
}
Matcher matcher = pattern.matcher(value);
if (!matcher.find()) {
throw new Exception("the value is not a number string :" + value);
}
//獲取字符串的第一個字符
char firstChar = value.charAt(0);
//data應該保存的是第一個非0數字後的字符串
if (firstChar == '-') { //說明輸入的是個負數
if (value.length() >=2) {
sign = firstChar;
value = value.substring(1);
value = getTemp(value); //得到value中第一個非0後的子字符串。
}
} else {
value = getTemp(value);
}
this.data = value.getBytes();
}
/**
* 得到一個字符串第一個非0後的字符串,如果沒有找到,則返回 "0" 。如:00003435534,則返回3435534
* @return
*/
private String getTemp(String value){
Pattern pattern = Pattern.compile("[^0]{1}");
Matcher matcher = pattern.matcher(value);
if (matcher.find()) {
value = value.substring(matcher.start());
} else {
value = "0";
}
return value;
}
public MyBigInteger add(MyBigInteger other) {
MyBigInteger result = new MyBigInteger();
int thisLength = this.data.length;
int otherLength = other.data.length;
int shorterLength = thisLength > otherLength ? otherLength : thisLength;
ArrayList<Byte> resultData = new ArrayList<Byte>();
int flag = 0; //表示相加時的 進位,或相減時的 借位
int i = thisLength - 1;
int j = otherLength - 1;
int k = shorterLength;
//兩個數的符號相同
if (other.sign == this.sign) {
//從兩個整數的個位開始依次相加
while (k > 0) {
Integer temp = new Integer(new String(new byte[]{this.data[i]})) + new Integer(new String(new byte[]{other.data[j]})) + flag;
flag = temp / 10; //相加結果超過10時的進位。沒有超過10,進位爲 0
resultData.add(0, ((temp % 10) + "").getBytes()[0]); //把相加結果保存起來
k--;
i--;
j--;
}
//把多出的位加入到結果中
if (i == -1) {
while (j >= 0) {
Integer temp = new Integer(new String(new byte[]{other.data[j]})) + flag;
flag = temp / 10;
resultData.add(0, ((temp % 10) + "").getBytes()[0]);
j--;
}
} else if (j == -1) {
while (i >= 0) {
Integer temp = new Integer(new String(new byte[]{this.data[i]})) + flag;
flag = temp / 10;
resultData.add(0, ((temp % 10) + "").getBytes()[0]);
i--;
}
}
//最後把flag加進結果中
if (flag != 0) {
for (byte by : (flag + "").getBytes()) {
resultData.add(0, by);
}
}
result.sign = other.sign;
} else { //符號不同
if (thisLength > otherLength) { //說明this表示的整數絕對值大,所以最終結果的符號爲this的符號
result.sign = this.sign;
resultData = subtract(this.data, other.data); //執行減法
} else if (thisLength < otherLength) { //other表示的整數絕對值大,所以最終結果的符號爲other的符號
result.sign = other.sign;
resultData = subtract(other.data, this.data);
} else { //如果兩個數據的位數相同
Integer thisInt = 0;
Integer otherInt = 0;
//從第一位開始比較,直到兩者不相等
for (int n = 0; n < thisLength; n++) {
thisInt = new Integer(new String(new byte[]{this.data[n]}));
otherInt = new Integer(new String(new byte[]{other.data[n]}));
if (!thisInt.equals(otherInt)) { //注意這裏要使用equals方法,因爲這裏需要比較的是兩者的內容
break;
}
}
//如果this的絕對值大
if (thisInt > otherInt) {
result.sign = this.sign;
resultData = subtract(this.data, other.data);
} else {
result.sign = other.sign;
resultData = subtract(other.data, this.data);
}
}
}
result.data = new byte[resultData.size()];
for (int m = 0; m < resultData.size(); m++) {
result.data[m] = resultData.get(m);
}
return result;
}
private ArrayList<Byte> subtract(byte[] larger, byte[] smaller) {
ArrayList<Byte> resultData = new ArrayList<Byte>();
int flag = 0;
int i = smaller.length - 1;
int j = larger.length - 1;
int k = smaller.length;
while (k > 0) {
Integer temp = new Integer(new String(new byte[]{larger[j]})) + flag - new Integer(new String(new byte[]{smaller[i]}));
if (temp < 0) { //如果相減結果小於0,說明需要借位,則把flag置爲 -1,以便下一位減去
flag = -1;
temp += 10;
} else { //如果大於零,需要把flag置爲 0.不要忘記了
flag = 0;
}
resultData.add(0, (temp + "").getBytes()[0]);
j--;
i--;
k--;
}
//下面的代碼就不寫註釋了
while (j >= 0) {
Integer temp = new Integer(new String(new byte[]{larger[j]})) + flag;
if (temp < 0) {
flag = -1;
temp += 10;
} else {
flag = 0;
}
resultData.add(0, (temp + "").getBytes()[0]);
j--;
}
return resultData;
}
@Override
public String toString() {
String str = new String(this.data);
str = getTemp(str);
if (sign == '-' && str !="0") {
str = sign + str;
}
return str;
}
}
MyBigIntegerTest.java
import junit.framework.TestCase;
import java.math.BigInteger;
/**
* Created by Rocky on 14-3-26.
*/
public class MyBigIntegerTest extends TestCase {
public void test1() throws Exception {
String a1 = "-5453450543044355356576980545345054545453453454344435353254545345054304435535657698087756454543454345454534534543444353532545453450543044355356454543454354353450136546534534545345345054353450136546534534545345345043044355356576980657698087756454543454354353450136546534534545345345054353450136546534534545345345043044355356576980877564545434543543534501877564545434543543534501";
String b1 = "4545453453454344435353254545345054304435535657698087756454543454354345454534534543444353532545453450543044355356576980877564545434545454534534564545434543543534501365465345345453453450543534501365465345345453453450430443553565769804344435353254545345054304435535657698087756454543454354353450136546534534545345345043543534501365465345345453453450534501365465345345453453450";
MyBigInteger a = new MyBigInteger(a1);
MyBigInteger b = new MyBigInteger(b1);
MyBigInteger c = a.add(b);
System.out.println(c);
BigInteger a2 = new BigInteger(a1);
BigInteger b2 = new BigInteger(b1);
BigInteger c2 = a2.add(b2);
System.out.println(c2);
System.out.println(c2.toString().equals(c.toString()));
}
}
結果: