题目:根据输入的算式,得出结果并输出。
注意: 1、输入为字符串类型,且输出结果保留两位小数 2、输入的字符串中可能含有括号 3、运算符只有:“+ - * / ( )”六种
解决方案:
使用Scanner中的nextLine方法输入字符串
String str = sc.nextLine(); 去除字符串中的空格、table等空白字符
str = str.replaceAll("\\s*", ""); 完成运算方法,运算得到结果
String getCalculatorAll(String str)
使用String类中的lastIndexOf方法,找到最内侧的左括号
int lindex = str.lastIndexOf("("); 如果不存在左括号,则:
if (lindex == -1)
判断是否存在右括号,则应抛出异常如果不存在右括号,则直接运算
if (str
.indexOf(")") != -1) {
throw new RuntimeException("输入的算式有误,请重新输入");
}
return getCalculator(str
);
如果存在左括号,则:
使用String类中的indexOf方法,判断是否存在右括号
int rindex = str.indexOf(")"); 如果不存在,则应抛出异常(如上述抛出异常代码)如果存在,即rindex的值就是第一次出现的索引位置
使用String类中的substring方法截取括号内的子字符串内容
String sub = str.substring(lindex + 1, rindex); 调用直接运算方法
String result = getCalculator(sub); 将算式字符串中的本次运算的括号内的子字符串用调用直接运算方法返回的字符串替代
str = str.substring(0, lindex) + result + str.substring(rindex + 1); 递归调用getCalculatorAll(String str)(即本身)
return getCalculatorAll(str); 无括号运算方法:String getCalculator(String str)
获取算式字符串中的数据列表和运算符列表,使用List
List
<Double> numlist
= getNumberList(str
);
List
<Character> operlist
= getOperList(str
);
先计算存在的乘除
遍历运算符列表operlist
for (int i
= 0; i
< operlist
.size(); i
++) {
Character oper
= operlist
.get(i
);
if (oper
== '*' || oper
== '/') {
operlist
.remove(i
);
double lnum
= numlist
.remove(i
);
double rnum
= numlist
.remove(i
);
numlist
.add(i
, oper
== '*' ? lnum
* rnum
: lnum
/ rnum
);
i
--;
}
}
再计算加减
while (!operlist
.isEmpty()) {
double lnum
= numlist
.remove(0);
double rnum
= numlist
.remove(0);
Character oper
= operlist
.remove(0);
numlist
.add(0, oper
== '+' ? lnum
+ rnum
: lnum
- rnum
);
}
返回值:
return String
.format("%.2f", numlist
.get(0));
获取运算符列表:List<Character> getOperList(String str)
清除干扰字符:负数前面的负号:‘-’替换为‘@’
调用替换负数负号方法:str = setSymbol(str); 遍历算式字符串,如果是运算符就添加至operlist列表中List
<Character> operlist
= new ArrayList<>();
for (int i
= 0; i
< str
.length(); i
++) {
char oper
= str
.charAt(i
);
if (oper
== '+' || oper
== '-' || oper
== '*' || oper
== '/') {
operlist
.add(oper
);
}
}
获取运算符列表:List<Double> getNumberList(String str)
清除干扰字符:负数前面的负号:‘-’替换为‘@’
调用替换负数负号方法:str = setSymbol(str); 将所有的“±*/”运算符替换为‘#’
str
= str
.replace("+","#");
str
= str
.replace("-","#");
str
= str
.replace("*","#");
str
= str
.replace("/","#");
然后根据‘#’切割,得到数据列表numlistString
[] num
= str
.split("#");
将原来变为‘@’的‘-’,即负数变为正常,使用Double包装类的parseDouble方法,将字符串转化为double类型数据 List
<Double> numlist
= new ArrayList<>();
for (String s
: num
) {
if (s
.charAt(0) == '@') {
s
= '-' + s
.substring(1);
}
numlist
.add(Double
.parseDouble(s
));
}
```
清除干扰字符:负数前面的负号:‘-’替换为‘@’:String setSymbol(String str)
for (int i
= 0; i
< str
.length(); i
++) {
char ch
= str
.charAt(i
);
if (ch
== '-') {
if (i
== 0) {
str
= '@' + str
.substring(1);
} else {
char ch2
= str
.charAt(i
- 1);
if (ch2
== '+' || ch2
== '-' || ch2
== '*' || ch2
== '/') {
str
= str
.substring(0, i
) + '@' + str
.substring(i
+ 1);
}
}
}
}
完整代码如下:
import java
.util
.ArrayList
;
import java
.util
.List
;
import java
.util
.Scanner
;
public class DemoMain {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
System
.out
.print("请输入算式:");
String str
= sc
.nextLine();
str
= str
.replaceAll("\\s*", "");
System
.out
.println(getCalculatorAll(str
));
}
private static String
getCalculatorAll(String str
) {
int lindex
= str
.lastIndexOf("(");
if (lindex
== -1) {
if (str
.indexOf(")") != -1) {
throw new RuntimeException("输入的算式有误,请重新输入");
}
return getCalculator(str
);
}
else {
int rindex
= str
.indexOf(")");
if (rindex
== -1) {
throw new RuntimeException("输入的算式有误,请重新输入");
}
else {
String sub
= str
.substring(lindex
+ 1, rindex
);
String result
= getCalculator(sub
);
str
= str
.substring(0, lindex
) + result
+ str
.substring(rindex
+ 1);
return getCalculatorAll(str
);
}
}
}
private static String
getCalculator(String str
) {
List
<Double> numlist
= getNumberList(str
);
List
<Character> operlist
= getOperList(str
);
for (int i
= 0; i
< operlist
.size(); i
++) {
Character oper
= operlist
.get(i
);
if (oper
== '*' || oper
== '/') {
operlist
.remove(i
);
double lnum
= numlist
.remove(i
);
double rnum
= numlist
.remove(i
);
numlist
.add(i
, oper
== '*' ? lnum
* rnum
: lnum
/ rnum
);
i
--;
}
}
while (!operlist
.isEmpty()) {
double lnum
= numlist
.remove(0);
double rnum
= numlist
.remove(0);
Character oper
= operlist
.remove(0);
numlist
.add(0, oper
== '+' ? lnum
+ rnum
: lnum
- rnum
);
}
return String
.format("%.2f", numlist
.get(0));
}
private static List
<Character> getOperList(String str
) {
str
= setSymbol(str
);
List
<Character> operlist
= new ArrayList<>();
for (int i
= 0; i
< str
.length(); i
++) {
char oper
= str
.charAt(i
);
if (oper
== '+' || oper
== '-' || oper
== '*' || oper
== '/') {
operlist
.add(oper
);
}
}
return operlist
;
}
private static List
<Double> getNumberList(String str
) {
str
= setSymbol(str
);
str
= str
.replace("+", "#");
str
= str
.replace("-", "#");
str
= str
.replace("*", "#");
str
= str
.replace("/", "#");
String
[] num
= str
.split("#");
List
<Double> numlist
= new ArrayList<>();
for (String s
: num
) {
if (s
.charAt(0) == '@') {
s
= '-' + s
.substring(1);
}
numlist
.add(Double
.parseDouble(s
));
}
return numlist
;
}
private static String
setSymbol(String str
) {
for (int i
= 0; i
< str
.length(); i
++) {
char ch
= str
.charAt(i
);
if (ch
== '-') {
if (i
== 0) {
str
= '@' + str
.substring(1);
} else {
char ch2
= str
.charAt(i
- 1);
if (ch2
== '+' || ch2
== '-' || ch2
== '*' || ch2
== '/') {
str
= str
.substring(0, i
) + '@' + str
.substring(i
+ 1);
}
}
}
}
return str
;
}
}