马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 naeb 于 2023-3-19 19:07 编辑
使用链表实现高精度整数加减法运算
输入数据可以采用每三位整数一组(中间加逗号),也可以不加逗号(比如: 100000000)。
(1)0;0;+ ,输出“0”。
(2)100,100,100;100,100,100,+,输出:200,200,200
(4)自选数据
问两个问题,我输入两个相同的数字后就会报错。另外我想要输入的数据中间加逗号要怎么改动?
请输入a:0
请输入b:0
请输入运算符:+
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin -3, end 0, length 0
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
at test.CopyOfIntegerAddSub.displayWithComma(CopyOfIntegerAddSub.java:229)
at test.CopyOfIntegerAddSub.main(CopyOfIntegerAddSub.java:33)
package test;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Scanner;
public class CopyOfIntegerAddSub {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("请输入a:");
String str_a = scan.next();
LinkedList list_a = Str2List(str_a);
System.out.print("请输入b:");
String str_b = scan.next();
LinkedList list_b = Str2List(str_b);
System.out.print("请输入运算符:");
String str_s = scan.next();
String str_pd = check(str_a, str_b, str_s); // 检查
Map map = Compare(list_a, list_b);
LinkedList max = (LinkedList) map.get("max");
LinkedList min = (LinkedList) map.get("min");
LinkedList flag = (LinkedList) map.get("flag");
//System.out.println(flag);
if (str_pd.length() > 0) {
System.out.println(str_pd);
} else {
if (str_s.equals("+")||max != min) {
String result_add = displayWithComma(add(max,min));
System.out.println("加法结果为:" + result_add);
} else if (str_s.equals("-")||max!=min) {
String result_sub = displayWithComma(sub(max, min));
if(flag.getFirst().equals("-")){
result_sub = "-" + result_sub;
}
System.out.println("减法结果为:" + result_sub);
}
}
}
/**
* 加法
*
* @param a
* @param b
* @return
*/
private static String add(LinkedList max, LinkedList min) {
int carry = 0; // 是否进位,1为进位
int r = 0; // 每位相加的结果
LinkedList result = new LinkedList();
int size_max = max.size(); // 链表a的长度
int size_min = min.size(); // 链表b的长度
for (int i = 0; i < size_max; i++) {
int max_i = Integer.parseInt(max.get(i).toString());
int min_i;
if (i < size_min) {
min_i = Integer.parseInt(min.get(i).toString());
} else {
min_i = 0;
}
r = max_i + min_i + carry;
if (r < 10) {
result.addFirst(r);
carry = 0;
} else {
result.addFirst(r % 10);
carry = 1;
if (i == size_max - 1) { // 控制最后一次循环;如果不加,最后一位相加时,不会把1存入链表
result.addFirst(carry);
}
}
}
String str = "";
for (int i = 0; i < result.size(); i++) {
str = str + result.get(i).toString();
}
return str;
}
/**
* 减法
*
* @param a
* @param b
* @return
*/
private static String sub(LinkedList max, LinkedList min) {
int borrow = 0; // 是否借位 1借
int r = 0; // 每位相减的结果
LinkedList result = new LinkedList();
int size_max = max.size(); // 链表a的长度
int size_min = min.size(); // 链表b的长度
for (int i = 0; i < size_max; i++) {
int max_i = Integer.parseInt(max.get(i).toString());
int min_i;
if (i < size_min) {
min_i = Integer.parseInt(min.get(i).toString());
} else {
min_i = 0;
}
r = max_i - min_i - borrow;
if (r < 0) {
result.addFirst(r + 10);
borrow = 1;
} else {
if (i == size_max - 1 && r == 0) { // 控制最后一次循环,两数相减如果为0,不显示0
break;
}
result.addFirst(r);
borrow = 0;
}
}
String str = "";
for (int i = 0; i < result.size(); i++) {
str = str + result.get(i).toString();
}
return str;
}
/**
* 比较大小
* @param a
* @param b
* @return
*/
private static Map<String, LinkedList> Compare(LinkedList a, LinkedList b) {
Map<String, LinkedList> map = new HashMap<String, LinkedList>(); // 为了可以返回多个值
int size_a = a.size(); // 链表a的长度
int size_b = b.size(); // 链表b的长度
LinkedList max = new LinkedList();
LinkedList min = new LinkedList();
LinkedList flag = new LinkedList();
if (size_a > size_b) {
max = a;
min = b;
flag.addFirst("+");
} else if (size_a < size_b) {
max = b;
min = a;
flag.addFirst("-");
} else {
for (int i = 0; i < size_a; i++) {
int a_i = Integer.parseInt(a.get(size_a - 1 - i).toString());
int b_i = Integer.parseInt(b.get(size_b - 1 - i).toString());
if (a_i == b_i) {
continue;
} else if (a_i < b_i) {
flag.addFirst("-");
max = b;
min = a;
break;
} else {
flag.addFirst("+");
max = a;
min = b;
break;
}
}
}
map.put("max", max);
map.put("min", min);
map.put("flag", flag);
return map;
}
/**
* 把字符串传入链表
*
* @param str
* @return
*/
private static LinkedList Str2List(String str) {
LinkedList<Character> list = new LinkedList<Character>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
list.addFirst(c);
}
// System.out.println("输出:"+list);
return list;
}
/**
* 处理字符串,每3位一格
*
* @param str
* @return
*/
public static String displayWithComma(String str) {
str = new StringBuffer(str).reverse().toString(); // 先将字符串颠倒顺序
String str2 = "";
int size = (str.length() % 3 == 0) ? (str.length() / 3)
: (str.length() / 3 + 1); // 每三位取一长度
/*
* 比如把一段字符串分成n段,第n段可能不是三个数,有可能是一个或者两个,
* 现将字符串分成两部分.一部分为前n-1段,第二部分为第n段.前n-1段,每一段加一",".而第n段直接取出即可
*/
for (int i = 0; i < size - 1; i++) { // 前n-1段
str2 += str.substring(i * 3, i * 3 + 3) + ",";
}
for (int i = size - 1; i < size; i++) { // 第n段
str2 += str.substring(i * 3, str.length());
}
str2 = new StringBuffer(str2).reverse().toString();
return str2;
}
/**
* 判断是否为数字
* @param str
* @return
*/
public static boolean isNumeric(String str) {
for (int i = str.length(); --i >= 0;) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 检查合法性
* @param str_a
* @param str_b
* @param str_s
* @return
*/
private static String check(String str_a, String str_b, String str_s) {
boolean result = true;
String str = "";
if ( isNumeric(str_a) == false) {
str = str + " a 为非法数值";
}
if (isNumeric(str_b) == false) {
str = str + " b 为非法数值";
}
if (!((str_s.equals("+")) || (str_s.equals("-")))) {
str = str + " 非法运算符";
}
return str;
}
}
|