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

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

 package Solution;

 /**
* 剑指offer面试题12相关题目:大位数加减乘法的实现、
* 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
* 把字符串翻转过来模拟从低位到高位的相加
* @author GL
*
*/
public class No12BigDigitalCalculate { /**
* 两个大数相加,默认两个大数位不带符号位的正数
* @param a
* @param b
* @return
*/
public static String bigDigitalSum(String a,String b){ //翻转两个字符串并转换成数组
char[] aArray=new StringBuffer(a).reverse().toString().toCharArray();
char[] bArray=new StringBuffer(b).reverse().toString().toCharArray();
int aLength=aArray.length;
int bLength=bArray.length; //两个整数相加的最大位数为两个整数中最大位数+1
int maxLength=aLength>bLength?aLength:bLength;
int[] result=new int[maxLength+1]; //按照数位对应相加
for(int i=0;i<maxLength+1;i++){
//判断当前位是否超过了当前数值的最大位数,如果是用0代替进行运算
int aInt=i<aLength?(aArray[i]-'0'):0;
int bInt=i<bLength?(bArray[i]-'0'):0;
result[i]=aInt+bInt;
} //处理进位,进位加到相邻的高位上
for(int i=0;i<result.length;i++){
if(result[i]>10){
result[i+1]=result[i+1]+result[i]/10;
result[i]=result[i]%10;
}
} StringBuffer realResult=new StringBuffer();
//判断是否有前置0,如果有不会打印出来
boolean isBeginning=true;
for(int i=result.length-1;i>=0;i--){
if(result[i]==0&&isBeginning)
continue;
else
isBeginning=false;
//从后向前将结果逆转
realResult.append(result[i]);
}
return realResult.toString();
} public static void main(String[] args) {
String a="88900988";
String b="7878778888";
System.out.println(bigDigitalSum(a,b)); }
}

两个大数相加

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

 package Solution;

 /**
* 剑指offer面试题12相关题目:大位数加减乘法的实现、
* 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
* 把字符串翻转过来模拟从低位到高位的相加
* @author GL
*
*/
public class No12BigDigitalCalculate { /**
* 两个大数相减,默认没有符号位,且都为正数
* @param a
* @param b
* @return
*/
public static String bigDigitalSub(String a,String b){
//翻转字符串并转化成数组
char[] aArray=new StringBuilder(a).reverse().toString().toCharArray();
char[] bArray=new StringBuilder(b).reverse().toString().toCharArray();
int aLength=aArray.length;
int bLength=bArray.length;
//找到最大的位数,两个整数的差的位数小于等于两个整数中的最大位数
int maxLength=aLength>bLength?aLength:bLength;
int[] result=new int[maxLength];
//判断结果符号
char sign='+';
if(aLength<bLength)
sign='-';
else if(aLength==bLength){
int i=maxLength-1;
while(i>0&&aArray[i]==bArray[i])
i--;
if(aArray[i]<bArray[i])
sign='-';
}
//开始计算结果集
for(int i=0;i<maxLength;i++){
int aInt=i<aLength?aArray[i]-'0':0;
int bInt=i<bLength?bArray[i]-'0':0;
if(sign=='-')
result[i]=bInt-aInt;
else
result[i]=aInt-bInt;
}
//处理结果集,如果结果集中的某一位小于0,则向高位借位,然后将本位加10
for(int i=0;i<maxLength-1;i++){
if(result[i]<0){
result[i+1]-=1;
result[i]+=10;
}
} //处理结果集,转化成真正结果
StringBuffer realResult=new StringBuffer();
if(sign=='-')
realResult.append('-');
boolean isBeginning=true;
for(int i=maxLength-1;i>=0;i--){
if(result[i]==0&&isBeginning){
continue;
}
else
isBeginning=false;
realResult.append(result[i]);
}
if(realResult.toString().equals(""))
realResult.append('0');
return realResult.toString();
} public static void main(String[] args) {
String a="88900988";
String b="7878778888";
System.out.println(bigDigitalSub(a,b));
}
}

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

 package Solution;

 /**
* 剑指offer面试题12相关题目:大位数加减乘法的实现、
* 解题思路:使用字符串表示数字,转换成数组进行计算。按位相加,然后处理进位
* 把字符串翻转过来模拟从低位到高位的相加
* @author GL
*
*/
public class No12BigDigitalCalculate { /**
* 两个大数相乘
* @param a
* @param b
* @return
*/
public static String bigDigitalMultiply(String a,String b){
//判断两字符串是否带有符号位,以及计算乘积的符号位
char signA=a.charAt(0);
char signB=b.charAt(0);
char sign='+';
if(signA=='+'||signA=='-'){
sign=signA;
a=a.substring(1);
}
if(signB=='+'||signB=='-'){
if(sign==-signB)
sign='+';
else
sign='-';
b=b.substring(1);
}
//将大数翻转,并转化为数组
char[] aArray=new StringBuffer(a).reverse().toString().toCharArray();
char[] bArray=new StringBuffer(b).reverse().toString().toCharArray();
int aLength=aArray.length;
int bLength=bArray.length;
int length=aLength+bLength;
int[] result=new int[length];
//计算结果集合
for(int i=0;i<aLength;i++){
for(int j=0;j<bLength;j++){
result[i+j]=result[i+j]+(aArray[i]-'0')*(bArray[j]-'0');
}
}
//处理结果集合,如果大于10的则向高位产生进位
for(int i=0;i<length-1;i++){
if(result[i]>10){
result[i+1]+=result[i]/10;
result[i]%=10;
} }
//把结果转化为正常序列
StringBuffer sb=new StringBuffer();
if(sign=='-')
sb.append('-');
boolean flag=true;
for(int i=length-1;i>=0;i--){
if(result[i]==0&&flag)
continue;
else
flag=false;
sb.append(result[i]);
}
if(sb.toString()=="")
sb.append('0');
return sb.toString();
} public static void main(String[] args) {
String a="88900988";
String b="7878778888";
System.out.println(bigDigitalMultiply(a,b)); }
}

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

剑指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. Intellij Idea 配置并发布tomcat项目

    作为一个菜鸟,我还是很想提高自己.但是既然说了是菜鸟,当然很容易半路折翅 从刚听说intellij idea(以下简称 idea)到现在,应该有超过一个月了吧,我的电脑装了三四次系统了(刚换了一台电脑 ...

  2. layer弹窗插件实战用法小结1—— layer.alert()

    http://layer.layui.com 第一节:layer.alert()弹窗的用法 1.解压layer-v2.2.zip压缩包 2.拷贝layer文件夹到实战项目目录 3.注意:layer.j ...

  3. 在官网下载了最新版的PHP,解压后的安装包里为什么没有php5isapi.dll这个dll文件?

    因为自PHP 5.3.1版本开始,PHP便已不在支持ISAPI模式,所以你在PHP5.3.1版本以上的php目录中看不到php5isapi.dll文件. 那么,IIS6下跑PHP 5.3.1以上版本时 ...

  4. QT第一天学习

    sudo apt-get install libqt4-dev回顾: 面向对象方法: 封装.继承.多态 封装:类 数据和操作 实现了信息隐藏 public: 类的内部 类的外部 private: pr ...

  5. Java 伪静态 Mapping

    1. 概念 伪静态,简单来说是指转换url地址,在这里用来替换掉urlMapping.因为urlMapping需要为每一个页面都进行配置,非常麻烦. 2. RequestMapping 3. Spri ...

  6. sqlloader外部表

    一创建目录 先在系统下创建 $ cd /home/oracle $ mkdir dir $ cd dir $ pwd 再在sqlplus里创建,让oracle知道这个目录 SQL> create ...

  7. FMS之Multi-point publishing技术

    采用该技术,能large-scale你的直播系统,结构如图所示: A. Live Video B. Server 1 (New York City)  C. Server 2 (Chicago) an ...

  8. I帧/P帧/B帧---术语解释

    视频压缩中,每帧代表一幅静止的图像.而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的.  简单地说,I帧是关键帧,属于帧内压缩.就是和AVI的压缩是一样的. P是向前搜索的意思.B ...

  9. 表单验证--通过原生js模仿ajax的异步交互

    今天给大家带来个福利,我也是刚刚学习的很实用的一个东西,通过原生js模仿ajax的异步交互. 我的博客只是给那些新手看的大神勿喷,写的不好可留言,请指出. 因为当初自己学的时候一个问题不会找人问,知道 ...

  10. 2017了,回家前 "年末" 分享:下雨,飘雪,红包雨,碰撞球,自定义View

    (本博客为原创:http://www.cnblogs.com/linguanh/) 目录: 效果展示 感想 代码拆解 开源地址 效果展示 有没有兴趣继续看下去,直接看下"颜值"是第 ...