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

    CALL DWord Ptr [<&KERNEL32.WriteFile>] kernel32.WriteFile 将数据写入一个文件,也可将这个函数应用于对通信设备.管道.套接字 ...

  2. 第一个shell脚本 结合计划任务下载远程文件

    思路: 进入/usr/local/apache2/htdocs/ipa/  循环读取 /root/shell/wget/down.txt  每次一行,每一行直接就是一条命令,直接 $line 就可以执 ...

  3. origin中把多个拟合曲线放在一张图

    双击其中一个.或者New一个graph.这里直接双击其中一个图. 右键,找到layer contents. 可以看到,一个scatter配一个polynomial fit line.把剩下的B,C,D ...

  4. 《疯狂Java讲义》(七)---- 方法

    一 方法的参数传递机制 Java方法的参数传递方式只有一种:值传递.就是将实际参数值的副本传入方法内,而参数本身不会受到任何影响. eg. 基本类型的值传递 public class Primitiv ...

  5. spring mvc 返回页面数据

    handler package com.stone.controller; import java.util.Map; import javax.servlet.http.HttpServletReq ...

  6. POJ1664(整数划分)

    放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30894   Accepted: 19504 Description ...

  7. JavaSE 教程的选择

    你好 我是大福 你现在看的是大福笔记 又降温了 下点小雨 出门有点冷 走路到公司20多分钟,又走的有点热 昨天说到了,今年的计划是从零开始重新学习并梳理下这两年学习和接触到的技术 那么今天开始第一个知 ...

  8. UE4中的集合:TSet容器

    好久没有更新了,最近一直在老家过年,网络不通的,今天才有时间更新一集. 一.TSet<T>是什么 UE4中,除了TArray动态数组外,还提供了各种各样的模板容器.这一节,我们就介绍集合容 ...

  9. JS数组处理

    一.定义数组: 方法1 var myCars=new Array(); myCars[0]="Saab"; myCars[1]="Volvo"; myCars[ ...

  10. 11g默认审计选项

    [注:参考了maclean的网文]11g默认审计选项AUDIT_TRAIL参数的缺省值为DB,审计数据记录在数据库中的AUD$审计字典基表上.在11g中CREATE SESSION将被作为受审计的权限 ...