一、题目描述
用Java编写一个计算器的控制台程序,支持加减乘除、乘方、括号、小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算。
二、输入描述
数字包括"0123456789",小数点为".",运算符包括:加("+")、减("-")、乘("*")、除("/")、乘方("^",注:不是**!)、括号("()")
需要从命令行参数读入输入,可以用 "1+2-3+4"的方式进行调用,不通过键盘输入
输入需要支持空格,即 main.java “1 + 2 - 3 + 4” 也需要程序能够正确给出结果
所有测试用例中参与运算的非零运算数的绝对值范围保证在 10^9 ~ 10 ^-(10) 之内, 应该输出运算结果时非零运算结果绝对值也保证在该范围内
三、输出描述
数字需要支持小数点,输出结果取10位有效数字,有效数字位数不足时不能补0
对于不在输入描述内的输入,输出INPUT ERROR
对于格式不合法(例如括号不匹配等)的输入,输出 FORMAT ERROR
对于不符合运算符接收的参数范围(例如除0等)的输入,输出VALUE ERROR
对于2、3、4的情况,输出即可,不能抛出异常
同时满足2、3、4中多个条件时,以序号小的为准
具体实现情况:乘方运算尚未扩展,不支持输入时运算式中包含负数但化简式中和结果可以是负数。输出结果取的是小数点后10位有效数字,与要求有点出入待修正。代码尚未重构优化。
实现代码:
import java.text.NumberFormat;
public class Main {
public static void main(String[] args) {
// write your code here
String format_process = "";
for(int i = 0; i < args.length; i++){
format_process = format_process + args[i];
//数字0-9和加减乘除小数点,44是逗号94是^乘方
}
//除空格
format_process = format_process.replace(" ","");
if(inputCorrect(format_process)){
if(formatCorrect(format_process)){
double a = reduceBracket(format_process);
if(Double.isInfinite(a) || !isAverage(a)){
System.out.println("VALUE ERROR");
//return "VALUE ERROR";
}else {
//System.out.println(result);
System.out.println("result" + validDigits(a));
}
}else {
System.out.println("FORMAT ERROR");
//return "FORMAT ERROR";
}
}else{
System.out.println("INPUT ERROR");
//return "INPUT ERROR";
}
}
//合法字符检测
public static Boolean inputCorrect(String str){
for(int i = 0; i < str.length(); i++) {
int chr = str.charAt(i);
if (chr >= 40 && chr <= 57 && chr != 44 || chr == 94 || chr == 32) {
return true;
} else {
return false;
}
}
if(str.length() == 0){
return false;
}
return null;
}
public static Boolean formatCorrect(String str){
//开头和结尾不能是符号
if(isHave(str.substring(0,1)) || isHave(str.substring(str.length()-1))){
return false;
}
//检测重复符号,从第二个字符开始至倒数第二个字符结束。
int j;
for(int i = 1; i < str.length() - 1; i++){
j = i + 1;
if(isHave(str.substring(i,i+1))&&isHave(str.substring(j,j+1))){
return false;
}
}
//左括号 右括号 括号中间不能为空
for(int i = 0; i < str.length(); i++){
if(i-1 >= 0){
if(str.charAt(i) == 40 && str.charAt(i-1) == 46){
return false;
}else if(str.charAt(i) == 41 && (isHave(str.substring(i-1,i)) || str.charAt(i-1) == 40)){
return false;
}
}
if(i+2 <= str.length()){
if(str.charAt(i) == 40 && (isHave(str.substring(i+1,i+2)) || str.charAt(i+1) == 41)){
return false;
}else if(str.charAt(i) == 41 && str.charAt(i+1) == 46){
return false;
}
}
}
//括号匹配
int left_bracket = 0;
for(int i = 0; i < str.length(); i++){
if(left_bracket < 0){
return false;
}else {
if(str.charAt(i) == 40){
left_bracket += 1;
}else if(str.charAt(i) == 41){
left_bracket -= 1;
}
}
}
if(left_bracket != 0){
return false;
}else {
return true;
}
}
private static Boolean isHave(String chr){
String sign[] ={"+","-","*","/","^","."};
for(int i = 0; i < sign.length; i++){
if(chr.equals(sign[i])){
return true;
}
}
return false;
}
public static String validDigits(double s){
System.out.println(s);
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(10);//设置保留多少位小数
nf.setGroupingUsed(false);// 取消科学计数法
String format_s = nf.format(s);
return format_s;
}
public static Boolean isAverage(Double s){
double max = 1E9;
double min = 1E-10;
if((Math.abs(s) <= max && Math.abs(s) >= min) || Math.abs(s)==0){
return true;
}else {
return false;
}
}
//去括号计算算式
public static double reduceBracket(String s){
String S = ""; //后缀
char[] Operators = new char[s.length()];
int Top = -1;
for (int i = 0; i < s.length(); i++)
{
char C = s.charAt(i);
switch(C)
{
case ' ' :
break;
case '+' : //操作符
case '-' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //出栈
if (c == '(')
{
Operators[++Top] = c; //入栈
break;
}else
{
S = S + c;
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '*' : //操作符
case '/' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
if (c == '+' || c == '-')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '(' : //操作符
Operators[++Top] = C;
S += " ";
break;
case ')' : //操作符
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
break;
}
else
{
S = S + c;
}
}
S += " ";
break;
default : //操作数
S = S + C;
break;
}
}
while (Top >= 0)
{
S = S + Operators[Top--]; //pop Operator
}
System.out.println(S); //后缀
//后缀表达式计算
double[] Operands = new double[S.length()];
double x, y, v;
Top = - 1;
String Operand = "";
for (int i = 0; i < S.length(); i++)
{
char c = S.charAt(i);
if ((c >= '0' && c <= '9') || c == '.')
{
Operand += c;
}
if ((c &#