下面是我自己编写的一个实现后缀表达式的代码,基本功能是实现了,但是还是存在不少的问题,本人小菜鸟一个,因此特在此向Java高手请求指点。下面是代码部分。
package com;import java.util.Scanner;
import java.util.Stack;public class TestCharAt {
public static void main(String[] args) {
TestCharAt c = new TestCharAt();
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个后缀表达式:");
String str = scan.nextLine();
System.out.println("计算结果:" + c.value(str));
}
/**
*后缀表达式执行计算
**/
public String value(String str){
Stack<Double> s = new Stack<Double>();
Double x,y;//定义x,y用于保存浮点数
float m;//定义m用于暂存函数运算的结果
char[] c = str.toCharArray();//转换为字符数组
int i = 0;
//扫描后缀表达式中的每个字符,并进行相应处理
try{
while(i<c.length){
char t = ' ';
if(c[i]==' ') {//扫描到空格字符不做任何处理
i++;continue;
}
switch(c[i]){
case '+': //做栈顶的两个元素的加法,和赋值给x
x=s.pop()+s.pop();
i++;break;
case '-': //做栈顶的两个元素的减法,差赋值给x
x=s.pop();//弹出减数
x=s.pop()-x;//弹出被减数
i++;break;
case '*': //做栈顶的两个元素的乘法,积赋值给x
x=s.pop()*s.pop();
i++;break;
case '/': //做栈顶的两个元素的除法,商赋值给x
x=s.pop();//弹出除数
if(x!=0.0)//弹出被除数,并计算
x=s.pop()/x;
else {//除数为0时,输出"除数不能为0"
return "除数不能为0!";
}
i++;break;
case '^'://乘方运算
x=s.pop();
x=Math.pow(s.pop(),x);
i++;break;
case '%'://求余运算
x=s.pop();
x=s.pop()%x;
i++;break;
case 'l'://对数函数运算
double a=s.pop();
if(a<=0){//底数必须为正数
return "输入无效";
}
else{
x=Math.log10(a);
}
i++;break;
case 's'://正弦函数运算
double x1 =s.pop();
if(Math.abs(x1) % 180 == 0){
x = 0.0;
}
else{
m=(float)Math.sin(x1*Math.PI/180);
x = (double) m;
}
i++;break;
case 'c'://余弦函数运算
double x2 =s.pop();
if(Math.abs(x2) % 180 == 90){
x = 0.0;
}
else{
m=(float)Math.cos(x2*Math.PI/180);
x = (double) m;
}
i++;break;
case 't'://正切函数运算
double x3=s.pop();
if(Math.abs(x3) % 180 == 90){//判断正切函数的输入值
return "输入无效";
}
else if(Math.abs(x3) % 180 == 0){
x = 0.0;
}
else{
m = (float) Math.tan(x3*Math.PI/180);
x = (double) m;
}
i++;break;
default://扫描到的是浮点数字符串,生成对应的浮点数
if(c[i]=='#'){
t = c[i];i++;
}
x=0.0;//利用x保存扫描到的整数部分的值
while(c[i]>=48 && c[i]<=57){
x=x*10+c[i]-48;i++;
}
if(c[i]=='.'){
i++;
y=0.0;//利用y保存扫描到的小数部分的值
Double j=10.0;
while(c[i]>=48 && c[i]<=57){
y = y+(c[i]-48)/j;
i++; j*=10;
}
x+=y;//把小数部分合并到整数部分输出
}
}
if(t=='#'){
x=-x;
}
s.push(x);//把扫描进行运算得到的浮点数压入栈中
} //end while
}catch(Exception e){
e.printStackTrace();
return "输入的表达式不是一个正确的后缀表达式";
}
if (s.empty()) {
return "输入为空,请输入表达式!";
}
x = s.pop();
if(s.empty()){
return x.toString();
}
return "输入的表达式不是一个正确的后缀表达式!";
}
}请看里面的case语句,前面使用的是 char[] c = str.toCharArray();//转换为字符数组
所以只能把sin,cos,tan,log简写为s,c,t,l 这里我主要是想把这个简写给还原,也就是说输入的是sin,比如输入的表达式是: 15 15 + sin (而不是15 15 + s)然后输出的结果是0.5, 请问该怎么样修改。
谢谢!Java栈StringMath
package com;import java.util.Scanner;
import java.util.Stack;public class TestCharAt {
public static void main(String[] args) {
TestCharAt c = new TestCharAt();
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个后缀表达式:");
String str = scan.nextLine();
System.out.println("计算结果:" + c.value(str));
}
/**
*后缀表达式执行计算
**/
public String value(String str){
Stack<Double> s = new Stack<Double>();
Double x,y;//定义x,y用于保存浮点数
float m;//定义m用于暂存函数运算的结果
char[] c = str.toCharArray();//转换为字符数组
int i = 0;
//扫描后缀表达式中的每个字符,并进行相应处理
try{
while(i<c.length){
char t = ' ';
if(c[i]==' ') {//扫描到空格字符不做任何处理
i++;continue;
}
switch(c[i]){
case '+': //做栈顶的两个元素的加法,和赋值给x
x=s.pop()+s.pop();
i++;break;
case '-': //做栈顶的两个元素的减法,差赋值给x
x=s.pop();//弹出减数
x=s.pop()-x;//弹出被减数
i++;break;
case '*': //做栈顶的两个元素的乘法,积赋值给x
x=s.pop()*s.pop();
i++;break;
case '/': //做栈顶的两个元素的除法,商赋值给x
x=s.pop();//弹出除数
if(x!=0.0)//弹出被除数,并计算
x=s.pop()/x;
else {//除数为0时,输出"除数不能为0"
return "除数不能为0!";
}
i++;break;
case '^'://乘方运算
x=s.pop();
x=Math.pow(s.pop(),x);
i++;break;
case '%'://求余运算
x=s.pop();
x=s.pop()%x;
i++;break;
case 'l'://对数函数运算
double a=s.pop();
if(a<=0){//底数必须为正数
return "输入无效";
}
else{
x=Math.log10(a);
}
i++;break;
case 's'://正弦函数运算
double x1 =s.pop();
if(Math.abs(x1) % 180 == 0){
x = 0.0;
}
else{
m=(float)Math.sin(x1*Math.PI/180);
x = (double) m;
}
i++;break;
case 'c'://余弦函数运算
double x2 =s.pop();
if(Math.abs(x2) % 180 == 90){
x = 0.0;
}
else{
m=(float)Math.cos(x2*Math.PI/180);
x = (double) m;
}
i++;break;
case 't'://正切函数运算
double x3=s.pop();
if(Math.abs(x3) % 180 == 90){//判断正切函数的输入值
return "输入无效";
}
else if(Math.abs(x3) % 180 == 0){
x = 0.0;
}
else{
m = (float) Math.tan(x3*Math.PI/180);
x = (double) m;
}
i++;break;
default://扫描到的是浮点数字符串,生成对应的浮点数
if(c[i]=='#'){
t = c[i];i++;
}
x=0.0;//利用x保存扫描到的整数部分的值
while(c[i]>=48 && c[i]<=57){
x=x*10+c[i]-48;i++;
}
if(c[i]=='.'){
i++;
y=0.0;//利用y保存扫描到的小数部分的值
Double j=10.0;
while(c[i]>=48 && c[i]<=57){
y = y+(c[i]-48)/j;
i++; j*=10;
}
x+=y;//把小数部分合并到整数部分输出
}
}
if(t=='#'){
x=-x;
}
s.push(x);//把扫描进行运算得到的浮点数压入栈中
} //end while
}catch(Exception e){
e.printStackTrace();
return "输入的表达式不是一个正确的后缀表达式";
}
if (s.empty()) {
return "输入为空,请输入表达式!";
}
x = s.pop();
if(s.empty()){
return x.toString();
}
return "输入的表达式不是一个正确的后缀表达式!";
}
}请看里面的case语句,前面使用的是 char[] c = str.toCharArray();//转换为字符数组
所以只能把sin,cos,tan,log简写为s,c,t,l 这里我主要是想把这个简写给还原,也就是说输入的是sin,比如输入的表达式是: 15 15 + sin (而不是15 15 + s)然后输出的结果是0.5, 请问该怎么样修改。
谢谢!Java栈StringMath
用else if 一样能达到效果。
第二,你接受输入比如说sin,你可以这样来解决
String str="sin";
char c = str.charAt(0);来获取第一个字符
额 就sin,写一个看看吧 真不是很清楚单字符char如何与多字符string处理。 谢谢!
就像我前面讲的,我现在能实现: 40 10 - s 结果是0.5
但是我需要的是输入: 40 10 - sin 结果是0.5
public enum OperateEnum {
PLUS("+"),
MINUS("-"),
SIN("sin");
//add other operator
OperateEnum(String code) {
this.setCode(code);
}
public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} private String code;
public static void main(String[] args) {
OperateEnum operator = code2Operator("sin");
if (operator == null) throw new NullPointerException("operator is null");
switch(operator) {
case MINUS :
System.out.format("do minus, operator[%s]",operator.getCode());
//do something;
break;
case PLUS :
System.out.format("do plus, operator[%s]",operator.getCode());
//do something;
break;
case SIN :
System.out.format("do sin, operator[%s]",operator.getCode());
break;
default:
}
}
public static OperateEnum code2Operator(String oper) {
for (OperateEnum eOper : OperateEnum.values()) {
if (eOper.getCode().equals(oper)) {
return eOper;
}
}
return null;
}
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
return (T)Enum.valueOf(enumType, name);
}
}