sqrt開平方算法解析
昨天筆試遇到一題,要求用java實現sqrt,當時就想,哪裏管過怎麽實現的,都是直接拿來用的。所以晚上就查了一些資料,將實現過程整理如下:
圖示:
算法思路(說明,下面的“碎片被開方數”,“補丁平方根”是為了方便稱呼自取的名稱):
- 1.將被開方數n從右向左兩位一劃分,例如將10517049劃分為10 51 70 49(可能是因為n的平方根肯定是n位數的一半吧,沒找到解釋的相關資料);
- 2.獲取“碎片被開方數”fragmentSqrt。從左向右每次取劃分好的兩位數,fragmentSqrt在第一次取值時就是n的最高一組兩位數(這裏是10),此後就是第4步計算的余數remainder
- 3.推測fragmentSqrt的“補丁平方根”patchRoot的個位bit_patchRoot;
推測公式為(high_patchRoot×2×10+bit_patchRoot)×bit_patchRoot,使其盡可能小於等於fragmentSqrt,循環bit_patchRoot從9~1即可。high_patchRoot為上一輪的補丁平方根”patchRoot。
推測公式的解釋:以1156為例,易觀察到它的平方根是兩位,十位是3,設個位是a,則(3
- 4.計算余數remainder;
remainder=fragmentSqrt-(high_patchRoot×2×10+bit_patchRoot)×bit_patchRoot
- 5.更正“補丁平方根
patchRoot=high_patchRoot×10+bit_patchRoot
- 6.返回第二步
①151為“碎片被開方數”fragmentSqrt
②2為bit_patchRoot
③3為high_patchRoot,即上一輪的patchRoot
④27為余數remainder
⑤32位patchRoot
①~⑤是第二輪結果
代碼
package kafka.productor;
import java.math.BigInteger;
import java.util.Scanner;
public class MySqrt {
static final BigInteger NUM20 = BigInteger.valueOf(20);// 將後面使用的參數定義為final常量
public static void main(String[] args) {
MySqrt mySqrt = new MySqrt();
Scanner input = new Scanner(System.in);
System.out.println(mySqrt.sqrt(input.next()));
}
public String sqrt(String n){
String patchRoot="0"; // 平方根初始化為字符串0
String remainder=""; //余數初始化為""
if(n.length()%2 != 0) n = "0"+n; //如果n是奇數為,防止substring越界
for(int i=0; i<n.length()/2; i++){//兩兩分組
String fragmentSqrt = remainder+n.substring(2*i,2*i+2); //第2步
String high_patchRoot = patchRoot;
String bit = getBit(new BigInteger(high_patchRoot),new BigInteger(fragmentSqrt)); //第3步
remainder = getRemainder(new BigInteger(fragmentSqrt),new BigInteger(high_patchRoot),new BigInteger(bit)); //第4步
patchRoot = high_patchRoot+bit; //第5步
}
return patchRoot.substring(1); // 去掉結果之前的0
}
private String getRemainder(BigInteger fragmentSqrt, BigInteger high_patchRoot, BigInteger bit_patchRoot) {
return fragmentSqrt.subtract(high_patchRoot.multiply(NUM20).add(bit_patchRoot).multiply(bit_patchRoot)).toString();
}
private String getBit(BigInteger high_patchRoot,BigInteger fragmentSqrt) {
int i;
for(i=9; i>0; i--){
BigInteger bi = BigInteger.valueOf(i);
if (fragmentSqrt.compareTo(high_patchRoot.multiply(NUM20).add(bi).multiply(bi))>=0)
break;
}
return String.valueOf(i);
}
}
參考
https://blog.csdn.net/Super2333/article/details/79476149
https://baike.baidu.com/item/%E5%BC%80%E5%B9%B3%E6%96%B9%E8%BF%90%E7%AE%97/1165387?fr=aladdin
為了得到而努力
2019-03-07
轉載請註明來處。
sqrt開平方算法解析