99的99次方----大数乘法和大数加法
2014-10-26 23:41
330 查看
记得室友跟我说过一件事,就是他以前实习时,当时的指导老师讲过一件事,就是有一回他们去参加IBM的笔试,笔试题目就是在纸上写程序算出99的99次方,当时很多人都很快做出来了,有简单的办法和巧妙的办法,做完后大家出来聊天,但发现还有一个家伙还没出来,结果等到结束后那家伙出来了,说他交了白卷。于是大家很奇怪,那么简单的题目怎么会交白卷呢?然后那家伙说了,那么大数,存在哪呢?他想半天也没想出来。。。
且不考虑这件事的具体细节和真实性,就这个问题而言,首先99的99次方应该是很大的了,long类型肯定装不下,其结果的位数应该接近200位(100的100次方是200位,所以99的99次方与其相比应该不会少到哪里去),但用String装应该绰绰有余了,直接的想法就是用String装数,模拟我们现实中的乘法即可。比如对于某个10进制4位数abcd作为被乘数,4位数efgh作为乘数的乘法运算,我们的乘法法则就是从乘数的最右端的个位数h开始,依次乘以abcd的个位直到万位,得到一个结果。然后乘数往左移动到十位数g,与先前一样,得到结果,但是要乘以10,再与先前的结果相加。重复这个过程,直到乘数的最高位,加上先前的结果得到最终答案。那么在这之前,还要完成大数的加法法则的模拟。大数的加法更容易实现,被加数和加数都从低位开始,逐个相加,直到最高位。
于是大数加法的算法要点:
(1)String类型的被加数num1,和加数num2
(2)用tag表示进位的值,默认为0
(3)第i次从num1和num2的末尾向左数第i位开始取字符,转换成int类型,与进位tag一起相加得到的结果取个位依次存入sum字符串中,十位的值存放到进位tag中。
(4)重复(2),(3)步骤,直到num1和num2全部位数相加完毕
大数乘法的算法要点:
(1)String类型的被乘数num1,和乘数num2
(2)用tag表示进位的值,默认为0
(3)第i次从乘数num2末尾左数第i位开始取字符,转换成int类型,依次与被乘数num1末尾向左数的每一位相乘,并与进位tag一起相加得到的结果取个位依次存入临时结果curSum字符串中,十位的值存放到进位tag中,还应在结果末尾添上i个0。
(4)调用大数加法,将i次的结果与第i-1次的结果相加。
(5)重复(2),(3),(4)的步骤,知道num2的全部位数都计算完毕,得到最终结果
代码如下:
大数加法代码:
大数乘法代码:
且不考虑这件事的具体细节和真实性,就这个问题而言,首先99的99次方应该是很大的了,long类型肯定装不下,其结果的位数应该接近200位(100的100次方是200位,所以99的99次方与其相比应该不会少到哪里去),但用String装应该绰绰有余了,直接的想法就是用String装数,模拟我们现实中的乘法即可。比如对于某个10进制4位数abcd作为被乘数,4位数efgh作为乘数的乘法运算,我们的乘法法则就是从乘数的最右端的个位数h开始,依次乘以abcd的个位直到万位,得到一个结果。然后乘数往左移动到十位数g,与先前一样,得到结果,但是要乘以10,再与先前的结果相加。重复这个过程,直到乘数的最高位,加上先前的结果得到最终答案。那么在这之前,还要完成大数的加法法则的模拟。大数的加法更容易实现,被加数和加数都从低位开始,逐个相加,直到最高位。
于是大数加法的算法要点:
(1)String类型的被加数num1,和加数num2
(2)用tag表示进位的值,默认为0
(3)第i次从num1和num2的末尾向左数第i位开始取字符,转换成int类型,与进位tag一起相加得到的结果取个位依次存入sum字符串中,十位的值存放到进位tag中。
(4)重复(2),(3)步骤,直到num1和num2全部位数相加完毕
大数乘法的算法要点:
(1)String类型的被乘数num1,和乘数num2
(2)用tag表示进位的值,默认为0
(3)第i次从乘数num2末尾左数第i位开始取字符,转换成int类型,依次与被乘数num1末尾向左数的每一位相乘,并与进位tag一起相加得到的结果取个位依次存入临时结果curSum字符串中,十位的值存放到进位tag中,还应在结果末尾添上i个0。
(4)调用大数加法,将i次的结果与第i-1次的结果相加。
(5)重复(2),(3),(4)的步骤,知道num2的全部位数都计算完毕,得到最终结果
代码如下:
大数加法代码:
package BigNum; public class BigNumAdd { private String num1st; // 被加数 private String num2nd; // 加数 public BigNumAdd() { } public BigNumAdd(String num1st, String num2nd) { this.num1st = num1st; this.num2nd = num2nd; } public String add() { StringBuffer sum = new StringBuffer(); int i = 0, a = 0, b = 0; int tag = 0; // 进位数 int j, k; // 被加数和加数的位置 j = num1st.length() - 1; //模拟加法法则 k = num2nd.length() - 1; while (j >= 0 || k >= 0 || tag > 0) { if (j >= 0) { a = num1st.charAt(j) - '0'; } else a = 0; if (k >= 0) { b = num2nd.charAt(k) - '0'; } else b = 0; try { if (a < 0 || a > 9 || b < 0 || b > 9) { throw new NumberFormatException(); } } catch (NumberFormatException e) { e.printStackTrace(); return "Argument Error!"; } i = a + b + tag; tag = i / 10; j--; k--; sum = new StringBuffer(String.valueOf(i % 10)).append(sum); } return sum.toString(); } }
大数乘法代码:
package BigNum; public class BigNumTimes { private String num1st; //被乘数 private String num2nd; //乘数 public BigNumTimes() { } public BigNumTimes(String num1st, String num2nd) { this.num1st = num1st; this.num2nd = num2nd; } public String times() { int i=0,a=0,b=0; int j,k; //位置标记 int tag=0; //进位数 StringBuffer sum=new StringBuffer(""); StringBuffer preSum=new StringBuffer("0"); StringBuffer curSum=new StringBuffer(""); k=num2nd.length()-1; //模拟乘法法则 while (k>=0) { for (int l=0;l<num2nd.length()-1-k;l++){ curSum.append("0"); } b=num2nd.charAt(k)-'0'; j=num1st.length()-1; while (j>=0 || tag>0){ if (j >= 0) { a = num1st.charAt(j) - '0'; } else a = 0; try { if (a<0 || a>9 || b<0 || b>9) { throw new NumberFormatException(); } }catch (NumberFormatException e){ e.printStackTrace(); return "Argument Error!"; } i=b*a+tag; tag=i/10; curSum=new StringBuffer(String.valueOf(i%10)).append(curSum); j--; } tag=0; k--; sum=new StringBuffer(new BigNumAdd(curSum.toString(),preSum.toString()).add()); //一轮结果相加 preSum=new StringBuffer(sum); curSum=new StringBuffer(""); } return sum.toString(); } //99的99次方 public static void main(String[] args){ String sum="1"; for (int i=1;i<=99;i++){ BigNumTimes bnt=new BigNumTimes(sum,"99"); sum=bnt.times(); System.out.println("99的"+i+"次方="+sum); } //System.out.println("位数="+sum.length()); } }
相关文章推荐
- 单链表实现大数加法、大数减法、大数乘法、大数指数运算
- 使用C++类实现大数加法,大数减法,大数乘法
- 大数与小数模板(乘法,加法)
- [acm 1001] c++ 大数加法 乘法 幂
- 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
- 【模版】大数乘法、加法模版
- sdut2613(This is an A+B Problem)大数加法(乘法)
- 大数运算之加法乘法---JAVA实现
- 大数加法乘法
- 大数加法、减法和乘法
- nefu 120 Lucas-Lehmer 梅森素数判别法 二分-大数乘法换加法
- 大数加法+乘法
- 大数运算——加法,减法,乘法 .
- nefu 120 Lucas-Lehmer 梅森素数判别法 二分-大数乘法换加法
- vector、string实现大数加法乘法
- 大数加法 减法 乘法 除法 高精度四则运算
- 大数加法乘法
- 大数运算,队列实现大数 加法、乘法、除法、模除
- 大数加法、减法、乘法、除法实现
- 整数大数模拟 高精度加法 高精度减法 高精度乘法 高精度除法 c/c++ java