用字符串或者数组表示大数是一种很简单有效的表示方式。在打印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. constrain to margins

    如果你点了constrain to margins,左右会有8个点的空挡,而是从8个点后开始计算约束,而没有点时,已屏幕的0点开始计算.

  2. 用Linux命令行获取本机外网IP地址

    引言:目前获取ip的方法中,ifconfig和ip获取函数得到的都是内网ip.有时候需要获取外网ip,目前通用的做法,是向外部服务器发送请求,解析外部服务器响应,从而得到的自己的外网ip.linux下 ...

  3. HTML URL

    HTML 统一资源定位器(Uniform Resource Locators) URL 是一个网页地址. URL可以由字母组成,如"runoob.com",或互联网协议(IP)地址 ...

  4. WCF服务发布到IIS中去 在WCF调试

    第一个WCF程序 1. 新建立空白解决方案,并在解决方案中新建项目,项目类型为:WCF服务应用程序.建立完成后如下图所示: 2.删除系统生成的两个文件IService1.cs与Service1.svc ...

  5. lufylegend库 LBitmapData LBitmap LSprite

    lufylegend库 LBitmapData LBitmap LSprite <!DOCTYPE html> <html lang="en"> <h ...

  6. 如何做到Zero Downtime重启Go服务?

    graceful的实践 使用endless库来实现,比如接入gin: r := gin.Default() r.GET("/", index) endless.ListenAndS ...

  7. ios NSString拼接方法总结

    NSString* string; // 结果字符串 02 NSString* string1, string2; //已存在的字符串,需要将string1和string2连接起来 03   04 / ...

  8. twemproxyRedis协议解析探索——剖析twemproxy代码正编

    这篇文章会对twemproxyRedis协议解析代码部分进行一番简单的分析,同时给出twemproxy目前支持的所有Redis命令.在这篇文章开始前,我想大家去简单地理解一下有限状态机,当然不理解也是 ...

  9. ubuntu-16.04(linux)使用Reaver爆破wifi密码(路由器的WPS功能漏洞)

    路由器的WPS功能 很多路由器都有WPS功能, 这边的WPS不是office工具软件, 而是路由器的一个功能: 路由器中WPS是由Wi-Fi联盟所推出的全新Wi-Fi安全防护设定(Wi-Fi Prot ...

  10. OVS VxLAN Flow 分析 - 每天5分钟玩转 OpenStack(149)

    OVS 的数据流向都是由 Flow 规则控制的,今天我们就来分析 VxLAN 的 Flow 规则.提个醒:这可能是本教程最烧脑的一节,let's rock it ! 下面分析控制节点上的 flow r ...