[程序设计实习]大整数的四则运算
2014-08-12 17:19
267 查看
描述
给出两个正整数以及四则运算操作符(+ - * /),求运算结果。
输入第一行:正整数a,长度不超过100 第二行:四则运算符o,o是“+”,“-”,“*”,“/”中的某一个 第三行:正整数b,长度不超过100
保证输入不含多余的空格或其它字符输出一行:表达式“a o b”的值。
补充说明: 1. 减法结果有可能为负数 2. 除法结果向下取整 3. 输出符合日常书写习惯,不能有多余的0、空格或其它字符
原来上课的时候是用C++写的,结果一不留神弄丢了,正好OJ上也没这道题的备份,就顺手用Java来写一个。
用C++写非常方便啊,直接建个类重载下运算符就可以了,Java就只能写成一个工具类和一大堆静态方法了,想想都难受。
以下仅限提供思路,请勿抄袭拿去交作业,欢迎批评吐槽效率/语法/细节(OJ只支持C++我也不知道这个能不能过啊!)。
由于每个数字最高可达100位,直接运算不但效率低下,还有可能出现精度丢失,于是采用将数字转换完字符串通过珠算方法按位计算,代码如下:
给出两个正整数以及四则运算操作符(+ - * /),求运算结果。
输入第一行:正整数a,长度不超过100 第二行:四则运算符o,o是“+”,“-”,“*”,“/”中的某一个 第三行:正整数b,长度不超过100
保证输入不含多余的空格或其它字符输出一行:表达式“a o b”的值。
补充说明: 1. 减法结果有可能为负数 2. 除法结果向下取整 3. 输出符合日常书写习惯,不能有多余的0、空格或其它字符
原来上课的时候是用C++写的,结果一不留神弄丢了,正好OJ上也没这道题的备份,就顺手用Java来写一个。
用C++写非常方便啊,直接建个类重载下运算符就可以了,Java就只能写成一个工具类和一大堆静态方法了,想想都难受。
以下仅限提供思路,请勿抄袭拿去交作业,欢迎批评吐槽效率/语法/细节(OJ只支持C++我也不知道这个能不能过啊!)。
由于每个数字最高可达100位,直接运算不但效率低下,还有可能出现精度丢失,于是采用将数字转换完字符串通过珠算方法按位计算,代码如下:
public class BigNumber { /** * 比较大小 */ private static int compare(String a, String b) { if (a.length() != b.length()) { //如果长度不等 通过长度差判断大小 return a.length() - b.length(); } else { for (int i = 0; i < a.length(); i++) { //如果长度相等 从头比较各位字符 通过字符ASCII码判断大小 if (a.charAt(i) != b.charAt(i)) { return a.charAt(i) - b.charAt(i); } } //长度和各位数字均相等 返回0表示大小相同 return 0; } } /** * 取相反数 */ private static String opposite(String a) { //正数添加负号,负数则去除负号 if (a.charAt(0) == '-') { return a.substring(1); } else { return "-" + a; } } /** * 加法运算 */ public static String add(String a, String b) { //将加数和被加数都转化成正数 if (a.charAt(0) == '-' && b.charAt(0) == '-') { return opposite(add(a.substring(1), b.substring(1))); } else if (a.charAt(0) == '-') { return subtract(b, a.substring(1)); } else if (b.charAt(0) == '-') { return subtract(a, b.substring(1)); } else { String result = ""; //通过填充0对齐位置 while (a.length() < b.length()) { a = "0" + a; } while (a.length() > b.length()) { b = "0" + b; } //设置进位符保存进位情况 int carry = 0; //珠算方法计算各位和 判断是否进位 直到结束 for (int i = a.length() - 1; i >= 0; i--) { int num = (a.charAt(i) - 48) + (b.charAt(i) - 48) + carry; if (num >= 10) { num -= 10; carry = 1; } else { carry = 0; } result = num + result; } if (carry == 1) { return 1 + result; } return result; } } /** * 减法运算 */ public static String subtract(String a, String b) { //将减数和被减数都转化成正数 并计算减数和被减数的大小关系 if (a.charAt(0) == '-' && b.charAt(0) == '-') { return opposite(subtract(a.substring(1), b.substring(1))); } else if (a.charAt(0) == '-') { return opposite(add(a.substring(1), b)); } else if (b.charAt(0) == '-') { return add(a, b.substring(1)); } else if (compare(a, b) < 0) { return opposite(subtract(b, a)); } else if (compare(a, b) == 0) { return "0"; } else { String result = ""; //通过填充0对齐位置 while (a.length() < b.length()) { a = "0" + a; } while (a.length() > b.length()) { b = "0" + b; } //设置退位符保存退位情况 int carry = 0; //与加法类似 珠算方法计算各位差 判断是否退位 直到结束 for (int i = a.length() - 1; i >= 0; i--) { int num = (a.charAt(i) - 48) - (b.charAt(i) - 48) - carry; if (num < 0) { num += 10; carry = 1; } else { carry = 0; } result = num + result; } if (result.charAt(0) == '0') { return result.substring(1); } return result; } } /** * 乘法运算 */ public static String multiply(String a, String b) { //将乘数和被乘数都转化成正数 并判断乘数和被乘数是否为0 if ("".equals(b.replaceAll("0", "")) || "".equals(b.replaceAll("0", ""))) { return "0"; } else if (a.charAt(0) == '-' && b.charAt(0) == '-') { return multiply(a.substring(1), b.substring(1)); } else if (a.charAt(0) == '-') { return opposite(multiply(a.substring(1), b)); } else if (b.charAt(0) == '-') { return opposite(multiply(a, b.substring(1))); } else { //循环取乘数的每一个位调用add方法进行累加 循环得出结果 也可以使用珠算方法每位都进行乘法 效率可能更高 String result = ""; String inner; int num; for (int i = 0; i < b.length(); i++) { num = b.charAt(i) - 48; inner = "0"; while (num-- > 0) { inner = add(inner, a); } result = add(result + 0, inner); } return result; } } /** * 除法运算 */ public static String divide(String a, String b) { //将除数和被除数都转化成正数 并判断除数是否为0 if ("".equals(b.replaceAll("0", ""))) { throw new RuntimeException("除数不能为0"); } else if (a.charAt(0) == '-' && b.charAt(0) == '-') { return divide(a.substring(1), b.substring(1)); } else if (a.charAt(0) == '-') { return opposite(divide(a.substring(1), b)); } else if (b.charAt(0) == '-') { return opposite(divide(a, b.substring(1))); } else if (compare(a, b) < 0) { return "0"; } else if (compare(a, b) == 0) { return "1"; } else { //与乘法类似 先将除数与被除数对齐 反复调用subtract方法 循环得出结果 String result = ""; int num; int len = b.length(); while (a.length() > b.length()) { b += "0"; } while (b.length() >= len) { num = 0; while (compare(a, b) >= 0) { num++; a = subtract(a, b); } result = result + num; b = b.substring(0, b.length() - 1); } if (result.charAt(0) == '0') { return result.substring(1); } return result; } } }
相关文章推荐
- 程序设计实习MOOC / 程序设计与算法(一)第三周测验(2017冬季)6:求整数的和与均值
- 第十五周C++【任务二】设计分数类,开发一个窗口式程序,可以完成分数的四则运算
- 身份证校验 如果让你设计个程序,用什么变量保存身份证号码呢?长整数可以吗?不可以! 因为有人的身份证最后一位是"X"
- 整数求和程序的流程设计和实现
- 【程序设计实习】笔记 6-005 间接基类
- PKU C++程序设计实习 学习笔记1
- 【程序设计实习】笔记 6--001继承
- PKU-程序设计实习-MySort函数
- 程序设计实习 构造函数相关 析构函数
- [程序设计实习]时光机
- 【程序设计实习】笔记 6--001继承
- C语言参考程序—无符号一位整数的四则运算
- 北大程序设计实习MOOC 编程作业 《魔兽世界之二:装备》
- 程序设计实习
- 程序实践系列(四)使用类设计整数集合类
- 程序设计实习 魔兽世界终极版 注意及代码~
- 【北大MOOC】2014程序设计实习--第二周编程作业
- 程序设计实习MOOC/第十三周编程作业/A:集合加法
- 对出四则运算程序升级的设计思想
- C++基本要点复习--------coursera程序设计实习(PKU)的lecture notes