编程题目:

拓展延伸:实现一个百亿级别的计算器。

示例代码:

package program.calculation.exercise70;/*** 拓展延伸:实现一个百亿级别的计算器。*/public class MyBigCalculator {public static void main(String[] args) {String str1 = "123789965783241232323512323676678";  String str2 = "23245235435436807768829454365465889"; //String str1 = "0000000000000100000000000000000000000000000000000002";  //String str2 = "000000000000050000000000000000000000000000000000000"; //String str1 = "2433456789";  //String str2 = "4345678";  System.out.println("两数之和:"+add(str1, str2));System.out.println("两数之差:"+subtract(str1, str2));System.out.println("两数之积:"+multiply(str1, str2));System.out.println("两数之商:"+divide(str1, str2));System.out.println("两数之余:"+remainder(str1, str2));}//相加private static String add(String str1,String str2){StringBuffer res = new StringBuffer(); //和(summary)//根据数字字符串的正负号,决定调用不同的方法if(str1.contains("-") && str2.contains("-")){str1 = str1.replace("-", "");str2 = str2.replace("-", "");return "-"+add(str1, str2);}else if((!str1.contains("-") && str2.contains("-"))){return subtract(str1,str2.replace("-", ""));}else if((str1.contains("-") && !str2.contains("-"))){return subtract(str2,str1.replace("-", ""));}//去除数字字符串前面的0,但注意应先去除正负号String s1 = str1.replaceAll("^0*", "");String s2 = str2.replaceAll("^0*", "");//如果两数均为0,则和为0,注意:此时0已被去除,为空白字符串if("".equals(s1) && "".equals(s2)){return "0";}//将两个数字的位数设为相同,不同的前面补0int len = Math.abs(s1.length()-s2.length());//返回两数相减的绝对值if(s1.length() > s2.length()){s2 = makeSameFigure(s2,len);}else{s1 = makeSameFigure(s1,len);}//两数的对应位数依次相加,大于9需要向前进位int n = 0; //需要进位的个数for(int i=s1.length()-1;i>=0;i--){//通过对应位数的数字字符的ASCII码相减获取数字int temp = (s1.charAt(i)-'0')+(s2.charAt(i)-'0')+n;//如果需要进位,则加上进位的个数if(i == 0){ //所有位数数字相加结束//temp%10:本位数字,temp/10:进位数字,如果为0,则不进位res.append(temp%10).append(temp/10==0?"":temp/10);//注意:此处从前往后添加,输出时倒序输出}else{res.append(temp%10); //将本位数字添加进结果中n = temp/10; //记录进位的个数}    }//去除首位数字0,并将StringBuffer类型的res转换为String类型,注意:输出需要倒序return kickFirstZero(String.valueOf(res.reverse()));}//相减private static String subtract(String str1,String str2){boolean flag = false;//判断被减数与减数的大小,false:被减数大于减数StringBuffer res = new StringBuffer(); //差(difference)//根据数字字符串的正负号,决定调用不同的方法if(str1.contains("-") && str2.contains("-")){return subtract(str2.replace("-", ""),str1.replace("-", ""));}else if((!str1.contains("-") && str2.contains("-"))){return add(str1,str2.replace("-", ""));}else if((str1.contains("-") && !str2.contains("-"))){return "-"+add(str2,str1.replace("-", ""));}//去除数字字符串前面的0,但注意应先去除正负号String s1 = str1.replaceAll("^0*", "");String s2 = str2.replaceAll("^0*", "");//如果两数相等,差为0,包括两数均为0的情况(其实此时为空白字符串,0已经被去除)if(s1.equals(s2)){return "0";}//如果被减数小于减数,则交换,同时将flag置为trueif(!isBigger(s1,s2)){flag = true;String temp = s1;s1 = s2;s2 = temp;}//将两个数字的位数设为相同,不同的前面补0s2 = makeSameFigure( s2,s1.length()-s2.length());//两数的对应位数依次相减,不够减需要向前借位int n = 0; //需要借位的个数for(int i=s1.length()-1;i>=0;i--){//通过对应位数的数字字符的ASCII码相减获取数字int temp = (s1.charAt(i)-'0')-(s2.charAt(i)-'0')-n;//再减去借位的个数if(i == 0){ //所有位数数字相减结束//如果最后位数数字为0,则转换为空白字符串res.append(temp==0?"":temp);//注意:此处是从后往前添加的,输出需要倒序}else{//如果位数数字大于等于0,则添加进结果,如果小于0,则需要借位+10,再相减res.append(temp>=0?temp:temp+10); n = temp>=0?0:1; //记录借位的个数}}//去除首位数字0,并将StringBuffer类型的res转换为String类型,注意:输出需要倒序String s = kickFirstZero(String.valueOf(res.reverse()));//如果flag=true,说明被减数小于减数,结果应加上负号-,return flag?"-"+s:s;}//相乘private static String multiply(String str1,String str2){String res = ""; //积(product)//判断积(product)的正负号int p = 0; //若p为偶数,积为正数,若p为奇数,积为负数if(str1.contains("-")){str1 = str1.replace("-", "");p++;}if(str2.contains("-")){str2 = str2.replace("-", "");p++;}//去除数字字符串前面的0,但注意应先去除正负号String s1 = str1.replaceAll("^0*", "");String s2 = str2.replaceAll("^0*", "");//如果两数有一个为0,则结果为0,注意:0已经被去除,此处为空白字符串if("".equals(s1) || "".equals(s2)){return "0";}//根据乘法的运算规则:被乘数分别乘以乘数的位数数字,然后再相加for(int i=s2.length()-1;i>=0;i--){ //乘数的位数//被乘数乘以乘数的位数数字n,其实也就是本身自加n次for(int j=0;j<s2.charAt(i)-'0';j++){ //通过ASCII码相减获取位数数字res = add(res,s1); //结果相加}s1 += "0"; //被乘数每乘以完乘数一个位数数字后,应进位,扩大10倍,字符串直接加0即可}//如果负号为奇数个,即c==1,则结果应为负数,加上"-"return p==1?"-"+res:res;} //相除private static String divide(String str1,String str2){String res = ""; //商(quotient)//判断商的正负号int q = 0; //若q为偶数,商为正数,若q为奇数,商为负数if(str1.contains("-")){str1 = str1.replace("-", "");q++;}if(str2.contains("-")){str2 = str2.replace("-", "");q++;}//去除数字字符串前面的0,但注意应先去除正负号String s1 = str1.replaceAll("^0*", "");String s2 = str2.replaceAll("^0*", "");//如果除数为0,表达式错误,注意:0已经被去除,此处为空白字符串if("".equals(s2)){return "ERROR";}//如果被除数绝对值小于除数绝对值,则商为0,或者被除数为0,注意:0已被去除,此处为空白字符串if(!isBigger(s1,s2) || "0".equals(s1)){return "0";}//如果被除数绝对值等于除数绝对值,则商绝对值为1if(s1.equals(s2)){res = "1"; //此处赋值给res,因为要添加正负号}else{ //主要处理被除数大于除数的情况//如果被除数的首位数字大于等于除数首位数字,则给被除数补一个零//此种情况如果不给被除数补一个零,则商会少最后一位数//原因:运行下面代码将位数置为相等后,此种情况下,其实被除数相当于少了一位数if(s1.charAt(0) >= s2.charAt(0)){s1 += "0";}//主要处理被除数位数大于除数位数的情况for (int n=s1.length()-s2.length();n>0;n--) { //n是s1与s2的位数差//除数补零操作,使除数的位数与被除数的位数相等while(s1.length() > s2.length()){s2 += "0";}//如果补零后被除数小于除数,则给被除数补一个零,否则进行下一步运算if (!isBigger(s1, s2)) {s1 += "0";}//循环找出 除数*i(i数0~9之间的数)的结果不大于被除数的最大i值,找到的i即为商的位数值for (int i=9;i>=0;i--) { //注意此处应倒序,因为循环找到不大于被除数的最大i值String temp = multiply(s2, String.valueOf(i));if (isBigger(s1, temp)) { //s1大于temp说明此时找到的i即为商的位数值s1 = subtract(s1, temp); //本次循环后的余数,作为下一次循环的被除数res += i; //将i添加到结果上break; //结束本次循环,开始执行下次循环}}    }    }//如果负号为奇数个,即c==1,则结果应为负数,加上"-"return q==1?"-"+res:res;}//取余private static String remainder(String str1,String str2){//第一种方式:取余运算:被除数-(商*除数)=余数,该方法比较取巧/*String quotient = divide(str1, str2); //获取两数之商String product = multiply(quotient, str2); //获取商和除数之积String difference = subtract(str1, product); //获取余数return difference;*///第二种方式:等同于除法,只不过进行了余数判断以及记录除数补0的次数String res = ""; //商(quotient)String rem = ""; //余数(remainder)//判断商(quotient)和余数(remainder)的正负号int q = 0; //若q为偶数,商为正数,若q为奇数,商为负数int r = 0; //若r为偶数,余数为正数,若r为奇数,余数为负数,根据被除数的正负号判断if(str1.contains("-")){str1 = str1.replace("-", "");q++;r++;}if(str2.contains("-")){str2 = str2.replace("-", "");q++;}//去除数字字符串前面的0,但注意应先去除正负号String s1 = str1.replaceAll("^0*", "");String s2 = str2.replaceAll("^0*", "");//如果除数为0,表达式错误,注意:0已经被去除,此处为空白字符串if("".equals(s2)){return "ERROR";}//如果被除数绝对值小于除数绝对值,则余数为被除数本身if(!isBigger(s1,s2)){rem = s1; //此处赋值给rem,因为要添加正负号}//记录除数在下面代码中补0的次数int count = 0; //除数每补一次0,就会导致余数结尾多一个0//如果被除数绝对值等于除数绝对值,则余数为0,或者被除数为0,注意:0已被去除,此处为空白字符串if(s1.equals(s2) || "".equals(s1)){return "0";}else{ //主要处理被除数大于除数的情况//如果被除数的首位数字大于等于除数首位数字,则给被除数补一个零//此种情况如果不给被除数补一个零,则商会少最后一位数//原因:运行下面代码将位数置为相等后,此种情况下,其实被除数相当于少了一位数if(s1.charAt(0) >= s2.charAt(0)){s1 += "0";}//主要处理被除数位数大于除数位数的情况for (int n=s1.length()-s2.length();n>0;n--) { //n是s1与s2的位数差//除数补零操作,使除数的位数与被除数的位数相等while(s1.length() > s2.length()){s2 += "0";count++; //除数每补一次0,count就加1}//如果补零后被除数小于除数,则给被除数补一个零,否则进行下一步运算if (!isBigger(s1, s2)) {s1 += "0";}//循环找出 除数*i(i数0~9之间的数)的结果不大于被除数的最大i值,找到的i即为商的位数值for (int i=9;i>=0;i--) { //注意此处应倒序,因为循环找到不大于被除数的最大i值String temp = multiply(s2, String.valueOf(i));if (isBigger(s1, temp)) { //s1大于temp说明此时找到的i即为商的位数值s1 = subtract(s1, temp); //本次循环后的余数,作为下一次循环的被除数res += i; //将i添加到结果上break; //结束本次循环,开始执行下次循环}} }    }//如果负号为奇数个,即q==1,则结果应为负数,加上"-"res = q==1?"-"+res:res; //商if("0".equals(s1)){ //如果s1为0,则不再去除多出的0rem = s1;}else{rem = s1.substring(0,s1.length()-count);//去除余数后面多出的0}//如果被除数为负数,即r==1,则结果应为负数,加上"-",注意:如果余数为0,就不需要再加上负号"-"return rem=="0"?rem:r==1?"-"+rem:rem;}//判断大小private static boolean isBigger(String str1,String str2){//去除数字字符串前面的正负号和0,但注意应先去除正负号String s1 = str1.replace("-", "").replaceAll("^0*", "");String s2 = str2.replace("-", "").replaceAll("^0*", "");if(s1.length() > s2.length()){return true;}else if(s1.length() < s2.length()){return false;}else if(s1.length() == s2.length()){for(int i=0;i<s1.length();i++){if(s1.charAt(i) < s2.charAt(i)){return false;}else if(s1.charAt(i) > s2.charAt(i)){return true;}}}return true;}//将两个数字位数设为相等private static String makeSameFigure(String s,int len){StringBuffer sb = new StringBuffer();for(int i=0;i<len;i++){sb.append("0");}s = String.valueOf(sb.append(s));return s; }//去除首位数字0private static String kickFirstZero(String s){while(s.length() > 1){if('0' == s.charAt(0)){//substring(0,index)表示获取下标为0-index(不包括)的元素s = s.substring(1); //注意:substring(index)表示去除下标为index的元素}else{break;}}return s;}}

结果显示:

拓展延伸: 实现一个百亿级别的计算器相关推荐

  1. 一个百亿级日志系统是怎么设计出来的?

    日志是记录系统中各种问题信息的关键,也是一种常见的海量数据. 日志平台为集团所有业务系统提供日志采集.消费.分析.存储.索引和查询的一站式日志服务. 主要为了解决日志分散不方便查看.日志搜索操作复杂且 ...

  2. 如何设计日志系统_架构 - 如何设计一个百亿级日志系统

    " 日志是记录系统中各种问题信息的关键,也是一种常见的海量数据. 日志平台为集团所有业务系统提供日志采集.消费.分析.存储.索引和查询的一站式日志服务. 主要为了解决日志分散不方便查看.日志 ...

  3. 大众点评:下一个百亿公司

    这家公司过去 8 年的"匍匐前进"正在变成自己最大的财富.随着因智能手机的普及而成为从线上通往线下的商业桥梁,大众点评网也迎来了自己成就百亿市值公司的机遇. 大众点评网的 CEO ...

  4. 2017年下一个百亿美金级创业机会的6个特征

    2016年倒下了一大批生鲜和汽车O2O独角兽:也崛起了类似摩拜单车.映客这样的新秀:今日头条确立了在内容平台的绝对领先地位:滴滴出行,和外卖市场在经历了恶战之后,开始规模化盈利了. 下一个百亿美金级的 ...

  5. java 百亿计算器_java面试题--实现一个百亿的计算器

    看了网上很多说法,没有具体把它实现的,我试了一下其实还是比较简单的. 直接看代码: packagecom.infomorrow;importjava.math.BigInteger;importorg ...

  6. Cocos 出席 36Kr AIGC 产业发展峰会,入选「下一个百亿规模 AIGC 产品」

    近日,36氪"WISE2023颠覆·AIGC产业发展峰会"在北京成功举办,该峰会聚焦从应用层到模型层.基础层的全产业链端口,以产业视角把握 AIGC 发展脉络,探寻新一代技术浪潮下 ...

  7. 一文即懂clickhouse 百亿级别实战

    要是想见,给我打个电话就行. 人和人谈不上义务性地见面,想见就见,想见才见. -- 村上春树 一.背景 ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域.目前国内 ...

  8. 如何处理百亿级别的数据信息

    导读:本次分享将从以下几个方面进行分享,首先讲一下我们目前所做的工作,目前平台架构是怎么样的,第二个是大量日志情况下如何收集,第三个涉及百亿数据后如何快速存储以及快速查询,第四个讲一下数据存储后如何对 ...

  9. 实现一个百亿计算器的基本思路

    package offer_pro.caculate;/*** @Auther: 大哥的叔* @Date: 2019/8/8 16:33* @Description:,要实现一个一百亿的计算器,我们得 ...

最新文章

  1. python 编程该看那些书籍_初学者自学Python要看什么书?
  2. 【Day13】说一下 Vue 组件的通信方式都有哪些?(父子组件,兄弟组件,多级嵌套组件等等)
  3. telegram 机器人_我在周末构建了一个无服务器的Telegram机器人。 这是我学到的。...
  4. python写音乐_Python国产库推荐之musicpy:让你用代码来写音乐
  5. Integer类的缓存机制
  6. ssm三大框架的优缺点
  7. 使用浏览器监控页面变化,语音播报变化内容
  8. 安全基础:0-day漏洞
  9. Android 支付宝支付功能实现
  10. win10计算器_你所不知道的 Windows 10 小诀窍:万能计算器、虚拟键盘、屏幕截图标注...
  11. 凝思系统激活序列号_凝思6.0虚拟机搭建--遇到的问题
  12. MTF SFR 简介
  13. 业务员怎么网上找客户?4个快速有效方法在这里
  14. Day739.GEO经纬度数据结构自定义数据结构 -Redis 核心技术与实战
  15. 几个寓意深远的小故事
  16. Python爬虫 抓取大数据岗位招聘信息(51job为例)
  17. Laravel框架中上传图片
  18. C语言基础——统计由键盘输入的一行字符中数字、字母与其他的个数
  19. C语言字符5,C语言字符数据(4、5).doc
  20. 中国手机支付行业竞争现状及市场发展格局分析报告2022-2028年版

热门文章

  1. 数据库工具——mongostat
  2. 实现swiper实现缩图
  3. 手把手教你使用SSM框架实现一个学生管理系统第二章之创建一个web工程及相关配置文件的介绍
  4. dos导入MySQL之后乱码_通过命令行导入到mysql数据库时出现乱码的解决方法
  5. java 获取字符串最后的数字
  6. 中国也曾有过贵族:春秋战国是其黄金时期
  7. IPD-产品需求管理过程(2)
  8. firebird嵌入式数据库
  9. 大连在线旅游网站推荐-找驴网
  10. 做一个python的旅游系统_Python爬取13个旅游城市,告诉你新年大家最爱去哪玩?...