用字符串或者数组表示大数是一种很简单有效的表示方式。在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式。在相关题实现任意两个整数的加法、减法、乘法的实现中,采用字符串对大数进行表示,不过在具体的计算中,还是要将字符串转化成字符数组来进行计算。

实现两个大数的加法,要考虑到两个问题,两个数的和的位数问题,以及如何处理两个数按位相加产生的进位问题。首先两个整数相加,两个数的和的位数最多比最大的整数的位数多1;这样和的位数就确定了。对于进位问题,我的做法是先进行按位相加,相加操作完成后再按照数位来判断是否需要进位,这样只需要遍历一下数组对于需要进位的为向高位进位就可以了。在计算两个数的加法的时候是要低位对其然后相加的,用字符串转化成的字符数组表示数字,数组的索引数字大的表示的是数字的低位,这样在计算过程中为了方便从数组的低索引开始算可以将字符串翻转,这样就很容易进行按位计算了。

  1. package Solution;
  2.  
  3. /**
  4. * 剑指offer面试题12相关题目:大位数加减乘法的实现、
  5. * 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
  6. * 把字符串翻转过来模拟从低位到高位的相加
  7. * @author GL
  8. *
  9. */
  10. public class No12BigDigitalCalculate {
  11.  
  12. /**
  13. * 两个大数相加,默认两个大数位不带符号位的正数
  14. * @param a
  15. * @param b
  16. * @return
  17. */
  18. public static String bigDigitalSum(String a,String b){
  19.  
  20. //翻转两个字符串并转换成数组
  21. char[] aArray=new StringBuffer(a).reverse().toString().toCharArray();
  22. char[] bArray=new StringBuffer(b).reverse().toString().toCharArray();
  23. int aLength=aArray.length;
  24. int bLength=bArray.length;
  25.  
  26. //两个整数相加的最大位数为两个整数中最大位数+1
  27. int maxLength=aLength>bLength?aLength:bLength;
  28. int[] result=new int[maxLength+1];
  29.  
  30. //按照数位对应相加
  31. for(int i=0;i<maxLength+1;i++){
  32. //判断当前位是否超过了当前数值的最大位数,如果是用0代替进行运算
  33. int aInt=i<aLength?(aArray[i]-'0'):0;
  34. int bInt=i<bLength?(bArray[i]-'0'):0;
  35. result[i]=aInt+bInt;
  36. }
  37.  
  38. //处理进位,进位加到相邻的高位上
  39. for(int i=0;i<result.length;i++){
  40. if(result[i]>10){
  41. result[i+1]=result[i+1]+result[i]/10;
  42. result[i]=result[i]%10;
  43. }
  44. }
  45.  
  46. StringBuffer realResult=new StringBuffer();
  47. //判断是否有前置0,如果有不会打印出来
  48. boolean isBeginning=true;
  49. for(int i=result.length-1;i>=0;i--){
  50. if(result[i]==0&&isBeginning)
  51. continue;
  52. else
  53. isBeginning=false;
  54. //从后向前将结果逆转
  55. realResult.append(result[i]);
  56. }
  57. return realResult.toString();
  58. }
  59.  
  60. public static void main(String[] args) {
  61. String a="88900988";
  62. String b="7878778888";
  63. System.out.println(bigDigitalSum(a,b));
  64.  
  65. }
  66. }

两个大数相加

实现两个大数相减和实现两个大数相加的思路相近,首先要判断两个数相减的差的位数问题。两个数的差的位数应该不多于最大的整数的位数(此处指两个正整数)。然后要考虑两个整数相减的差的符号问题,如果被减数的位数少于减数的位数,那么得到的差值应该是负号。然后考虑按位相减产生的借位问题的处理方式,同按位相加的进位一样,先让各个数位相减,然后统一处理借位问题。

  1. package Solution;
  2.  
  3. /**
  4. * 剑指offer面试题12相关题目:大位数加减乘法的实现、
  5. * 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
  6. * 把字符串翻转过来模拟从低位到高位的相加
  7. * @author GL
  8. *
  9. */
  10. public class No12BigDigitalCalculate {
  11.  
  12. /**
  13. * 两个大数相减,默认没有符号位,且都为正数
  14. * @param a
  15. * @param b
  16. * @return
  17. */
  18. public static String bigDigitalSub(String a,String b){
  19. //翻转字符串并转化成数组
  20. char[] aArray=new StringBuilder(a).reverse().toString().toCharArray();
  21. char[] bArray=new StringBuilder(b).reverse().toString().toCharArray();
  22. int aLength=aArray.length;
  23. int bLength=bArray.length;
  24. //找到最大的位数,两个整数的差的位数小于等于两个整数中的最大位数
  25. int maxLength=aLength>bLength?aLength:bLength;
  26. int[] result=new int[maxLength];
  27. //判断结果符号
  28. char sign='+';
  29. if(aLength<bLength)
  30. sign='-';
  31. else if(aLength==bLength){
  32. int i=maxLength-1;
  33. while(i>0&&aArray[i]==bArray[i])
  34. i--;
  35. if(aArray[i]<bArray[i])
  36. sign='-';
  37. }
  38. //开始计算结果集
  39. for(int i=0;i<maxLength;i++){
  40. int aInt=i<aLength?aArray[i]-'0':0;
  41. int bInt=i<bLength?bArray[i]-'0':0;
  42. if(sign=='-')
  43. result[i]=bInt-aInt;
  44. else
  45. result[i]=aInt-bInt;
  46. }
  47. //处理结果集,如果结果集中的某一位小于0,则向高位借位,然后将本位加10
  48. for(int i=0;i<maxLength-1;i++){
  49. if(result[i]<0){
  50. result[i+1]-=1;
  51. result[i]+=10;
  52. }
  53. }
  54.  
  55. //处理结果集,转化成真正结果
  56. StringBuffer realResult=new StringBuffer();
  57. if(sign=='-')
  58. realResult.append('-');
  59. boolean isBeginning=true;
  60. for(int i=maxLength-1;i>=0;i--){
  61. if(result[i]==0&&isBeginning){
  62. continue;
  63. }
  64. else
  65. isBeginning=false;
  66. realResult.append(result[i]);
  67. }
  68. if(realResult.toString().equals(""))
  69. realResult.append('0');
  70. return realResult.toString();
  71. }
  72.  
  73. public static void main(String[] args) {
  74. String a="88900988";
  75. String b="7878778888";
  76. System.out.println(bigDigitalSub(a,b));
  77. }
  78. }

实现两个大数的乘法,两个整数的乘积的位数最多为两个整数的位数的和,两个整数相乘的计算方式的规律是,被乘数的第i位和乘数的第j位进行乘法运算的结果是算在乘积的第i+j位上的,比如两个整数的各位相乘,结果应该在乘积的个位上(暂时不考虑进位),个位和十位相乘得结果在积的十位上,这样就可以像加减法一样,按照数位算出两个数相乘,各个数位的值,然后再集中处理进位的问题。

  1. package Solution;
  2.  
  3. /**
  4. * 剑指offer面试题12相关题目:大位数加减乘法的实现、
  5. * 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
  6. * 把字符串翻转过来模拟从低位到高位的相加
  7. * @author GL
  8. *
  9. */
  10. public class No12BigDigitalCalculate {
  11.  
  12. /**
  13. * 两个大数相乘
  14. * @param a
  15. * @param b
  16. * @return
  17. */
  18. public static String bigDigitalMultiply(String a,String b){
  19. //判断两字符串是否带有符号位,以及计算乘积的符号位
  20. char signA=a.charAt(0);
  21. char signB=b.charAt(0);
  22. char sign='+';
  23. if(signA=='+'||signA=='-'){
  24. sign=signA;
  25. a=a.substring(1);
  26. }
  27. if(signB=='+'||signB=='-'){
  28. if(sign==-signB)
  29. sign='+';
  30. else
  31. sign='-';
  32. b=b.substring(1);
  33. }
  34. //将大数翻转,并转化为数组
  35. char[] aArray=new StringBuffer(a).reverse().toString().toCharArray();
  36. char[] bArray=new StringBuffer(b).reverse().toString().toCharArray();
  37. int aLength=aArray.length;
  38. int bLength=bArray.length;
  39. int length=aLength+bLength;
  40. int[] result=new int[length];
  41. //计算结果集合
  42. for(int i=0;i<aLength;i++){
  43. for(int j=0;j<bLength;j++){
  44. result[i+j]=result[i+j]+(aArray[i]-'0')*(bArray[j]-'0');
  45. }
  46. }
  47. //处理结果集合,如果大于10的则向高位产生进位
  48. for(int i=0;i<length-1;i++){
  49. if(result[i]>10){
  50. result[i+1]+=result[i]/10;
  51. result[i]%=10;
  52. }
  53.  
  54. }
  55. //把结果转化为正常序列
  56. StringBuffer sb=new StringBuffer();
  57. if(sign=='-')
  58. sb.append('-');
  59. boolean flag=true;
  60. for(int i=length-1;i>=0;i--){
  61. if(result[i]==0&&flag)
  62. continue;
  63. else
  64. flag=false;
  65. sb.append(result[i]);
  66. }
  67. if(sb.toString()=="")
  68. sb.append('0');
  69. return sb.toString();
  70. }
  71.  
  72. public static void main(String[] args) {
  73. String a="88900988";
  74. String b="7878778888";
  75. System.out.println(bigDigitalMultiply(a,b));
  76.  
  77. }
  78. }

在两个大数相乘的实现中考虑到了输入的数组中带有符号的问题,而在两位数加减的实现中只是实现了最基本的两个整数的加减,而且在三个实现中都没有对字符串所表示的数字进行有效性检验,在实现任意两个带符号的加减法中,可先判断字符串的有效性,然后检查是否带符号,最后调用无符号加法和无符号减法来取得结果,比如两个负数相减可以求得两个正数的和然后加负号,一个正数与一个负数相加可以采用两个无符号数相减来实现。

剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现的更多相关文章

  1. 剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈

    剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()- ...

  2. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  3. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  4. 剑指Offer——网易校招内推笔试题+模拟题知识点总结

    剑指Offer--网易校招内推笔试题+模拟题知识点总结 前言 2016.8.2 19:00网易校招内推笔试开始进行.前天晚上利用大约1小时时间完成了测评(这个必须做,关切到你能否参与面试).上午利用2 ...

  5. 剑指Offer——知识点储备-Java基础

    剑指Offer--知识点储备-Java基础 网址来源: http://www.nowcoder.com/discuss/5949?type=0&order=0&pos=4&pa ...

  6. 剑指Offer——栈的java实现和栈的应用举例

    剑指Offer--栈的java实现和栈的应用举例 栈是一种先进后出的数据结构, 栈的实现如下: 首先定义了栈需要实现的接口: public interface MyStack<T> { / ...

  7. 剑指offer题解(Java版)

    剑指offer题解(Java版) 从尾到头打印链表 题目描述 输入一个链表,按从尾到头的顺序返回一个ArrayList. 方法1:用一个栈保存从头到尾访问链表的每个结点的值,然后按出栈顺序将各个值存入 ...

  8. 剑指Offer——美团内推+校招笔试题+知识点总结

    剑指Offer--美团内推+校招笔试题+知识点总结 前言 美团9.9内推笔试.9.11校招笔试,反正就是各种虐,笔试内容如下: 知识点:图的遍历(DFS.BFS).进程间通信.二叉查找树节点的删除及中 ...

  9. 剑指Offer——联通研究院笔、面试题 (Offer已收割)

    剑指Offer--联通研究院笔.面试题 1.二叉树适宜存储什么样的数据? 树最适合用来表示( C ). A.有序数据元素 B.无序数据元素 C.元素之间具有分支层次关系的数据 D.元素之间无联系的数据 ...

随机推荐

  1. jquery 中prop()的使用方法

    1:设置input的选中属性:$('.passenger').find('.is-need-tel').prop('checked',true); 2:获取input是否选中: $('.passeng ...

  2. 线程(thread)

    线程(thread): 现代操作系统引入进程概念,为了并发(行)任务 1.进程之间的这种切换代价很高 2.通信方式的代价也很大基本概念: 1.线程是比进程更小的资源单位,它是进程中的一个执行路线(分支 ...

  3. 关于IE6、IE7、IE8实现盒子阴影shadow的几个注意点

    通常,我们实现盒阴影都是通过这段代码来实现的 -moz-box-shadow: 3px 3px 4px #000; -webkit-box-shadow: 3px 3px 4px #000; box- ...

  4. bootstrap的alert提示框的关闭后再显示问题

    bootstrap中有alert组件,如果点击关闭按钮后该组件会被删除而不是被隐藏,想再显示怎么办呢? bootstrap-alert.js源码片段: function removeElement() ...

  5. Everything开机自启

    第一步:关闭自动启动 在设置中关闭everything开机自动启动. 第二步:创建计划任务 点击“开始”—“任务计划程序”—“创建任务” 首先设置任务的名称等,注意一定要勾选“使用最高权限运行”. 然 ...

  6. swift中标签的使用

    1,标签的创建 1 2 3 4 5 6 7 8 9 10 import UIKit class ViewController: UIViewController {     override func ...

  7. LCA 倍增

    最近公共祖先 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. #include<cstdio> #include&l ...

  8. Linux安装配置VPN服务器

    一.实验简介 VPN ,中文翻译为虚拟专有网络,英文全称是 Virtual Private Network .现在 VPN 被普遍定义为通过 一个公用互联网络建立一个临时的.安全的连接,是一条穿过混乱 ...

  9. WPF DataPager控件

    最近在项目中遇到远程加载数据的问题,由于服务器采用分页方式返回数据,因此客户端也相应的制作了一个分页控件.代码相对简单,算做入门级的源码. 效果如图: 初步分析,分页功能只需要3个核心变量:PageI ...

  10. 在MyEclipse 2014中给Spket增加ExtJS提示

    参考:http://wenku.baidu.com/link?url=BT2U6Z-HktQJQYpz3Jp88pJSp4lU-lXkvCqpdeaa9a-BVdOgMGK1vj486-32YC4Gq ...