大整数相乘
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
大整數(shù)相乘,輸入小數(shù)也可以,其原理是分塊相乘,將輸入的數(shù)對半分成高位和低位,使大整數(shù)劃分為小數(shù),然后將小數(shù)相乘獲取原高地位的大數(shù)
可以通過規(guī)律:大整數(shù)1*大整數(shù)2=高位1*高位2+中位進位+中位(高位1乘低位2+低位1乘高位2)+低位進位+低位1*低位2
拼接大整數(shù)
java代碼如下:
// 分塊相乘
public?String bigMul(String num1, String num2,?int?len) {
if?(null?== num1 ||?"".equals(num1) ||?null?== num2 ||?""?== num2) {
return?"0";
}
int?pointNum = 0;// 小數(shù)點移位距離
// 如果是小數(shù)
if?(num1.contains(".")) {
pointNum += num1.length()-num1.indexOf(".")-1;
String h = num1.substring(0, num1.indexOf("."));
String l = num1.substring(num1.indexOf(".") + 1);
num1 = h + l;
}
if?(num2.contains(".")) {
pointNum += num2.length()-num2.indexOf(".")-1;
String h = num2.substring(0, num2.indexOf("."));
String l = num2.substring(num2.indexOf(".") + 1);
num2 = h + l;
}
// 取得最長的數(shù)
// 將長度調(diào)整相同
num1 =?formatNumber(num1, len);
num2 =?formatNumber(num2, len);
// 如果長度小于4,則直接乘
if?(num1.length() <= 4) {
String result = String.valueOf(Integer.valueOf(num1)
* Integer.valueOf(num2));
String setPoint = setPoint(pointNum, result);
return?setPoint;
}
// 如果長度大于四,將兩個數(shù)分成高低位
int?halfLen = len / 2;
int?halfLen2 = len - halfLen;
String num1H = num1.substring(0, halfLen);
String num1L = num1.substring(halfLen);
String num2H = num2.substring(0, halfLen);
String num2L = num2.substring(halfLen);
int?maxLen = Math.max(halfLen, halfLen2);
// 高位*高位
String H1H2 = bigMul(num1H, num2H, halfLen);
// 高位*低位
String H1L2 = bigMul(num1H, num2L, maxLen);
// 低位乘高位
String L1H2 = bigMul(num1L, num2H, maxLen);
// 低位*低位
String L1L2 = bigMul(num1L, num2L, halfLen2);
// 從低位開始,先取低位的進位
String[] carryL = getCarry(L1L2, halfLen2);
// 將中間兩位相加
String mid = additionMid(H1L2, L1H2);
String carry = carryL[0];
if?(carry !=?null?&& !carry.equals("0")) {
mid = additionMid(mid, carry);
}
// 首位加上中位進位再取進位
String[] carryMid = getCarry(mid, maxLen);
String carryM = carryMid[0];
String high =?"";
high = additionMid(H1H2, carryM);
// 將三者疊加即可
String result = high + carryMid[1] + carryL[1];
result = setPoint(pointNum, result);
return?result;
}
private?String setPoint(int?pointNum, String result) {
// 設(shè)置小數(shù)點
if?(pointNum > 0) {
String sRes =?"."?+ result.substring(result.length() - pointNum);
String hRes = result.substring(0, result.length() - pointNum);
result = hRes + sRes;
}
return?result;
}
private?String additionMid(String h1l2, String l1h2) {
int?carryFlag = 0;
int?maxLength = Math.max(h1l2.length(), l1h2.length());
h1l2 =?formatNumber(h1l2, maxLength);
l1h2 =?formatNumber(l1h2, maxLength);
String numRes =?"";
String[] result = {?"0", numRes };
for?(int?i = maxLength - 1; i >= 0; i--) {
int?num1 = Integer.parseInt(h1l2.substring(i, i + 1));
int?num2 = Integer.parseInt(l1h2.substring(i, i + 1));
int?singleAddition = num1 + num2 + carryFlag;
carryFlag = 0;
if?(singleAddition >= 10) {
carryFlag = 1;
singleAddition -= 10;
}
numRes = singleAddition + numRes;
}
result[0] = String.valueOf(carryFlag);
result[1] = numRes;
// 如果最高位有進位,則加上去
if?(carryFlag != 0) {
numRes = carryFlag + numRes;
}
return?numRes;
}
// 0:進位,1:值
private?String[] getCarry(String l1l2,?int?len) {
String carry[] = {?"0", l1l2 };
if?(l1l2.length() > len) {
// 有進位
int?sub = -len + l1l2.length();// 獲得多出來的長度
String substring = l1l2.substring(0, sub);// 截取進位長度
String valueString = l1l2.substring(sub);// 截取進位后的長度
carry[0] = substring;
carry[1] = valueString;
}?else?{
for?(int?i = l1l2.length(); i < len; i++) {
carry[1] =?"0"?+ carry[1];
}
}
return?carry;
}
@Test
public?void?fun() {
//首數(shù)字不能為零
String num1 =?"14.4";
String num2 =?"1.42";
String bigMul = bigMul(num1, num2,
Math.max(num1.length(), num2.length()));
bigMul = getPruNum(bigMul);
System.out.println(bigMul);
}
private?String getPruNum(String bigMul) {
for?(int?i = 0; i < bigMul.length(); i++) {
String w = bigMul.substring(0, 1);
if?(w.equals("0")) {
bigMul = bigMul.substring(1);
}?else?{
return?bigMul;
}
}
return?bigMul;
}
轉(zhuǎn)載于:https://my.oschina.net/zhouzhenBlog/blog/648151
總結(jié)
- 上一篇: python.re模块
- 下一篇: 帝国cms调用栏目自定义字段(栏目简介)