计算器由java语言实现
没有学栈的可以先学一下栈
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class chap3_3 {
public static boolean IsOperator(char c){
switch (c){
case '#':
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
return true;
default:
return false;
}
}
static char OP[][]={
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','E'},
{'>','>','>','>','E','>','>'},
{'<','<','<','<','<','E','='},
};
public static int GetOperatorID(char Operator){
int retCode;
retCode = -1;
switch (Operator){
case '+':
retCode = 0;
break;
case '-':
retCode = 1;
break;
case '*':
retCode = 2;
break;
case '/':
retCode = 3;
break;
case '(':
retCode = 4;
break;
case ')':
retCode = 5;
break;
case '#':
retCode = 6;
break;
}
return retCode;
}
public static char Precede(char Operator1, char Operator2){
int OperatorID1, OperatorID2;
OperatorID1 = GetOperatorID(Operator1);
OperatorID2 = GetOperatorID(Operator2);
if (OperatorID1<0 || OperatorID2<0 || OperatorID1>6 || OperatorID2>6){
return ('E');
}
return OP[OperatorID1][OperatorID2];
}
public static double Operate(double op1,char cal,double op2)
{
switch (cal)
{
case '+':
return op1+op2;
case '-':
return op1-op2;
case '*':
return op1*op2;
case '/':
return op1/op2;
default:
return 0;
}
}
public static double ExpEvaluation(char []exp){
char thera;
int i = 0;
double b,a,val;
sequenceStack <Character> OPTR = new sequenceStack<Character>();
sequenceStack <Double> OPND = new sequenceStack<Double>();
OPTR.push('#');
while(exp[i]!='#' || OPTR.getHead()!='#'){
if(!IsOperator(exp[i])){
double temp;
temp = exp[i] - '0';
i++;
while (!IsOperator(exp[i]) && i<exp.length){
temp = temp*10 + exp[i] - '0';
i++;
}
OPND.push(temp);
}
else{
switch (Precede(OPTR.getHead(),exp[i])){
case '<':
OPTR.push(exp[i]);
i++;
break;
case '=':
OPTR.pop();
i++;
break;
case '>':
thera = OPTR.pop();
b = OPND.pop();
a = OPND.pop();
OPND.push(Operate(a,thera,b));
break;
case 'E':
System.out.println("表达式错误");
return 0;
}
}
}
val = OPND.pop();
return val;
}
public static void main(String[] args) {
BufferedReader br;
String s;
try{
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入以#结尾的表达式:");
s = br.readLine();
char []exp = s.toCharArray();
System.out.println("表达式的值为:"+ExpEvaluation(exp));
}catch (IOException e)
{
e.printStackTrace();
}
}
}
该程序实现了一个基本的计算器,能够处理带有 +
、-
、*
和 /
运算符以及括号的算术表达式。#
符号用于表示表达式的结束。
这个Java程序实现了一个表达式计算器,使用了两栈算法进行表达式求值。用户以字符串的形式输入表达式,程序计算其值。
让我们分解程序的关键组成部分:
-
IsOperator(char c):
- 一个方法,检查一个字符是否是运算符(
+
、-
、*
、/
、(
、)
、#
)。
- 一个方法,检查一个字符是否是运算符(
-
OP[][]:
- 一个二维数组,表示运算符优先级表。它定义了不同运算符之间的优先级关系。
-
GetOperatorID(char Operator):
- 一个方法,根据给定的运算符字符返回运算符的ID。
-
Precede(char Operator1, char Operator2):
- 一个方法,使用运算符优先级表(
OP[][]
)确定两个运算符之间的优先级关系。
- 一个方法,使用运算符优先级表(
-
Operate(double op1, char cal, double op2):
- 一个方法,对两个操作数执行指定的算术运算(
+
、-
、*
、/
)。
- 一个方法,对两个操作数执行指定的算术运算(
-
ExpEvaluation(char[] exp):
- 主要的表达式求值方法,使用两栈算法。
- 它使用两个栈(
OPTR
用于运算符,OPND
用于操作数)来求值表达式。 - 算法遍历表达式,根据运算符的优先级执行相应的操作。
-
main(String[] args):
- 主方法,从用户那里读取一个表达式字符串,将其转换为字符数组,然后调用
ExpEvaluation
方法计算并打印结果。
- 主方法,从用户那里读取一个表达式字符串,将其转换为字符数组,然后调用
-
BufferedReader br; String s; try...catch 块:
- 处理用户从
BufferedReader
输入表达式,并捕获可能的IOException
。
- 处理用户从
op二维数组:
(1)‘#’的优先级最低,当‘#’=‘#’表示整个表达式结束。
(2)同级别的算符遇到时,左边算符的优先级高于右边算符的优先级,如‘+’与‘+’、‘-’与‘-’、‘+’与‘-’等。
(3)‘(’在左边出现时,其优先级低于右边出现的算符,如‘+’、‘-’、‘*’等,‘(’=‘)’表示括号内运算结束;‘(’在右边出现时,其优先级高于左边出现的算符,如‘+’、‘-’、‘*’等。
(4)‘)’在左边出现时,其优先级高于右边出现的算符,如‘+’、‘-’、‘*’等;‘)’在右边出现时,其优先级低于左边出现的算符,如‘+’、‘-’、‘*’等。
(5)‘)’与‘(’、‘#’与‘)’、‘(’与‘#’之间无优先关系,在表达式中不允许相继出现,如果出现认为是语法错误。