华为OJ------高精度整数加法
来源:互联网 发布:十万块钱怎么理财 知乎 编辑:程序博客网 时间:2024/05/16 06:55
题目描述
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-231~231-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:9876543210 + 1234567890 = ?让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。-9876543210 + (-1234567890) = ?让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。要求编程实现上述高精度的十进制加法。要求实现方法: public String add (String num1, String num2)【输入】num1:字符串形式操作数1,如果操作数为负,则num1的前缀为符号位'-'num2:字符串形式操作数2,如果操作数为负,则num2的前缀为符号位'-'【返回】保存加法计算结果字符串,如果结果为负,则字符串的前缀为'-'注:(1)当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;(2)输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;(3)要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
输入描述
输入两个字符串
输出描述
输出给求和后的结果
输入例子
98765432101234567890
输出例子
11111111100
算法实现
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);// Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data2.txt")); while (scanner.hasNext()) { String n = scanner.next(); String m = scanner.next(); // 【1】方法一 System.out.println(add(n, m)); // 【2】方法二// BigInteger bi1 = new BigInteger(n);// BigInteger bi2 = new BigInteger(m);// System.out.println(bi1.add(bi2)); } scanner.close(); } /** * 大整数相加,n、m都为自然数 * * @param ns 数字 * @param ms 数字 * @return 结果 */ private static String add(String ns, String ms) { // ns是否为正数 boolean pn = ns.charAt(0) != '-'; // ms是否为正数 boolean pm = ms.charAt(0) != '-'; int[] n; int[] m; if (pn) { n = getNumber(ns); } else { n = getNumber(ns.substring(1)); } if (pm) { m = getNumber(ms); } else { m = getNumber(ms.substring(1)); } // 两者同号 if (pn == pm) { // 进行计算 int[] r = add(m, n); String rs = toNumber(r); // 根据需要添加负号 if (pn) { return rs; } else { return "-" + rs; } } else { // ns的绝对值比大于等于ms if (compare(n, m) >= 0) { int[] r = minus(n, m); String rs = toNumber(r); // ns为正数,ms为负数 if (pn) { return rs; } else { return "-" + rs; } } // ns的绝对值比小于ms else { int[] r = minus(m, n); String rs = toNumber(r); // ns为正数,ms为负数 if (pn) { return "-" + rs; } else { return rs; } } } } /** * 两个整数相加 * * @param m 整数 * @param n 整数 * @return 结果 */ private static int[] add(int[] m, int[] n) {// System.out.println(Arrays.toString(n) +"\n"+ Arrays.toString(m)); // 保证n不小于m if (m.length > n.length) { int[] t = m; m = n; n = t; } // 结果的最大长度 int[] r = new int[n.length + 1]; // 来自低位的进位 int c = 0; for (int i = 0; i < m.length; i++) { r[i] = m[i] + n[i] + c; c = r[i] / 10; r[i] %= 10; } // 计算余下的部分 for (int i = m.length; i < n.length; i++) { r[i] = n[i] + c; c = r[i] / 10; r[i] %= 10; }// System.out.println(Arrays.toString(n) +"\n"+ Arrays.toString(m) + "\n" + Arrays.toString(r)); // 最后还有进位 if (c != 0) { r[r.length - 1] = c; return r; } // 没有进位 else { int[] ret = new int[r.length - 1]; System.arraycopy(r, 0, ret, 0, ret.length); return ret; } } /** * 比较两个整数是否相等,下标由小到大表示由低位到高位,忽略最高有效位上的前导0 * * @param m 整数 * @param n 整数 * @return m > n返回1,m = n返回0,m < n返回-1 */ private static int compare(int[] m, int[] n) { if (m == null && n == null) { return 0; } // null最小 if (m == null) { return -1; } if (n == null) { return 1; } int lastM = m.length - 1; int lastN = n.length - 1; // 找m的最高有效位的位置,至少有一位 while (lastM >= 1 && m[lastM] == 0) { lastM--; } // 找n的最高有效位的位置,至少有一位 while (lastN >= 1 && n[lastN] == 0) { lastN--; } // m的数位比n多,说明m比n大 if (lastM > lastN) { return 1; } // m的数位比n少,说明m比n小 else if (lastM < lastN) { return -1; } else { // 位数一样,比较每一个数位上的值,从高位到低位进行比较 for (int i = lastM; i >= 0; i--) { if (m[i] > n[i]) { return 1; } else if (m[i] < n[i]) { return -1; } } return 0; } } /** * 做减法n-m,保证n大于等于m * * @param n 整数 * @param m 整数 * @return 结果 */ private static int[] minus(int[] n, int[] m) { n = format(n); m = format(m); int[] r = new int[n.length]; // 当前位被借位 int c = 0; int t; for (int i = 0; i < m.length; i++) { t = n[i] - c - m[i]; // 当前位够减 if (t >= 0) { r[i] = t; // 没有进行借位 c = 0; } // 不够减 else { r[i] = t + 10; // 进行借位 c = 1; } } // 还有借位或者n比m位数多,要将n中的数位复制到r中 for (int i = m.length; i < n.length; i++) { t = n[i] - c; // 当前位够减 if (t >= 0) { r[i] = t; // 没有进行借位 c = 0; } // 不够减 else { r[i] = t + 10; // 进行借位 c = 1; } } return format(r); } /** * 将整数字符串表示成整数数组【包含符号位】 * * @param n 整数字符串 * @return 整数数组 下标从小到大表示数位的从低到高 */ private static int[] getNumber(String n) { int[] r = new int[n.length()]; for (int i = 0; i < r.length; i++) { r[i] = n.charAt(n.length() - i - 1) - '0'; } return r; } /** * 将整数进行格式化,去掉高位的前导0 * * @param r 整数 * @return 结果 */ private static int[] format(int[] r) { int t = r.length - 1; // 找最高有效位 while (t > 0 && r[t] == 0) { t--; } int[] nr = new int[t + 1]; System.arraycopy(r, 0, nr, 0, nr.length); return nr; } /** * 将数组表示的整数转换成字符串 * * @param r 整数 * @return 字符串表示的整数 */ private static String toNumber(int[] r) { if (r == null) { return null; } StringBuilder b = new StringBuilder(r.length); for (int i = r.length - 1; i >= 0; i--) { b.append(r[i]); } return b.toString(); }}
0 0
- 华为OJ------高精度整数加法
- 华为OJ(高精度整数加法)
- 高精度整数加法(OJ)
- 【华为OJ】【039-无线OSS-高精度整数加法】
- 华为OJ——无线OSS-高精度整数加法
- 华为OJ——无线OSS-高精度整数加法
- 华为上机题:高精度整数加法
- 【华为机试】无线OSS-高精度整数加法
- 九度OJ-1198:a+b (高精度整数加法)
- 高精度 大整数加法
- 高精度整数加法
- 高精度整数加法
- 高精度大整数加法
- 高精度整数加法
- OJ 高精度加法
- 高精度整数加法(大整数加法)
- 高精度整数(包括负数)加法
- 高精度(大整数加法)
- 转:百度MySql5.7安装配置
- 关于安卓实现简单的微信盆友圈分享
- BIOS没有开启虚拟化问题disabled by bios
- 使用 PHP 解析 User agent 信息
- setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)的使用
- 华为OJ------高精度整数加法
- js 笔记
- ubuntu keepalived 安装
- Unity内建的Shader
- Android webView 缓存 Cache + HTML5离线功能 解决
- CakePHP系列(二)----Bookmarker案例(一)
- 使用 LVS 实现负载均衡原理及安装配置详解
- grub中的import_unicode.py 分析之二
- 在腾讯云上搭建服务器