**50分**求助在计算器中如何实现多项式计算问题 转成后序表达式看看数据结构的书就有这方面的或者导入javascrip,javascript或vbscript都有这方面的支持函数的 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我有一个大概的想法,但我在代码实现的时候,遇到了问题用两个栈(operate,data),一个用来存放操作符号(如:+ - * /)另一个用来存放要操作的数据例:3+5*2-2当按下3按钮时,data栈将数据3压入栈中.当按下+号按钮时,先判断栈中有无"+"或"-",如果有则将data栈中前两个数据pop,并pop operate栈中的符号并加以计算,计算后从新压入data栈中operate栈将"+"压入栈中,.....当按下"*"或"/"时,判断operate中是否有"*""/",如果是,则将符号和数据弹出,计算,压入栈中,再将新按下的符号压入栈中..........我觉得这个办法应该没问题吧?编译通过了但运行是老是出错,高人快来看看 import java.applet.*;import java.awt.*;import java.util.*;public class Calculator extends Applet { public void init() { setLayout(new BorderLayout()); Panel p1=new Panel(); p1.setBackground(Color.gray);//设置p1的背景色 display=new ExpTextField("",30); p1.add(display); p1.add(new Button("清空")); add("North",p1); Panel p2=new Panel(); p2.setLayout(new GridLayout(3,6));//网格布局 p2.add(new Button("7")); p2.add(new Button("8")); p2.add(new Button("9")); p2.add(new Button("(")); p2.add(new Button(")")); p2.add(new Button("=")); p2.add(new Button("4")); p2.add(new Button("5")); p2.add(new Button("6")); p2.add(new Button(".")); p2.add(new Button("+")); p2.add(new Button("-")); p2.add(new Button("1")); p2.add(new Button("2")); p2.add(new Button("3")); p2.add(new Button("0")); p2.add(new Button("*")); p2.add(new Button("/")); add("Center",p2); } public boolean action(Event e,Object a)//按钮事件的action方法 { if(a instanceof String) { if(a.equals("清空"))//清空 { display.setText(""); return true; } display.setText(display.getText()+(String)a); if(a.equals("="))//当用户按下=键开始计算 display.setText(EvaluateExpression.calculate(display.getText())); return true; } else return super.action(e,a);//如果事件没有处理,将事件传输到该类在继承体系中父类去处理 } private ExpTextField display;}class ExpTextField extends TextField{ public ExpTextField(String s,int n) { super(s,n); } public boolean keyDown(Event e,int key) { if(key==61)//=键 { setText(getText()+"="); setText(EvaluateExpression.calculate(getText())); return true; } else if(key==27)//Esc键 { setText(""); return true; } else if((key>=40)&&(key<=57)&&(key!=44)//数字或运算符 ||(key==8)||(key==127)//Backspace键或delete键 ||(key==Event.LEFT)||(key==Event.RIGHT)//左右键 ||(key==Event.HOME)||(key==Event.END))//Home键或End键 return super.keyDown(e,key); else //忽略其它键 return true; }}class EvaluateExpression //算符优先算法{ public static String calculate(String exp) { char lastoptr='='; char c; char ch; double d1;//操作数 double d2;//操作数 String opnd=" "; String result; Stack optrstack=new Stack();//运算符栈 Stack opndstack=new Stack();//操作数栈 optrstack.push(new Character('=')); try { for(int i=0;i<exp.length();i++) { c=exp.charAt(i);//输入的字符 if(Character.isDigit(c)||(c=='.'))//操作数 { opnd=opnd+c; } else if((c=='+')||(c=='-')||(c=='*')||(c=='/')||(c=='(')||(c==')')||(c=='='))//运算符 { if((c=='-')&&opnd.equals("")&&((lastoptr=='=')||(lastoptr=='('))) c='@';//c为负号 if(!opnd.equals("")) { opndstack.push(new Double(opnd));//进操作数栈 opnd=""; } while(getF(((Character)optrstack.peek()).charValue())>getG(c))//比较优先权 { ch=((Character)optrstack.pop()).charValue(); if(ch=='@')//一个操作数的情况 { d1=((Double)opndstack.pop()).doubleValue(); opndstack.push(new Double(-d1)); } else//两个操作数的情况 { d2=((Double)opndstack.pop()).doubleValue(); d1=((Double)opndstack.pop()).doubleValue(); opndstack.push(new Double(cal(d1,d2,ch))); } } if(getF(((Character)optrstack.peek()).charValue())<getG(c))//比较优先权 { optrstack.push(new Character(c)); lastoptr=c; continue; } if(getF(((Character)optrstack.peek()).charValue())==getG(c))//比较优先权 { optrstack.pop(); lastoptr=c; continue; } } else return("ERROR"); } result=((Double)opndstack.pop()).toString(); if((!optrstack.empty())||(!opndstack.empty())) result="ERROR"; } catch(NumberFormatException e) { result="ERROR"; } catch(ArithmeticException e) { result="ERROR"; } return result; } private static int getF(char c)//运算符栈顶元素优先函数 { switch(c) { case'+': case'-': return 2; case'*': case'/': return 4; case'@': return 5; case'(': return 0; case')': return 6; case'=': return 0; default: return -1; } } private static int getG(char c)//输入的运算符优先函数 { switch(c) { case'+': case'-': return 1; case'*': case'/': return 3; case'@': return 6; case'(': return 7; case')': return 0; case'=': return 0; default: return -1; } } private static double cal(double d1,double d2,char c) { switch(c) { case'+': return(d1+d2); case'-': return(d1-d2); case'*': return(d1*d2); case'/': return(d1/d2); default: return -1; } }} 我曾经给别人的答复转成后序表达式最容易解析比如a + (b + c) * d - e转成a,b,c,+,d,*,+,e,-(具体转换你自己看数据结构的书吧,主要是自己定义好运算符的优先级,然后逐个压栈退栈等等)例如:list(保存元素用),stack(运算符压栈出栈用)1)运算符优先级 "(,)"大于"*,/,%"大于"+,-"2)压栈出栈规则,当遍历到的运算符的优先级小于或等于栈顶运算符的优先级时,栈中运算符出栈,直到遇到栈中运算符的优先级比其小为止,然后将其压栈;遇到"("时直接压栈,遇到")"时栈中运算符出栈,直到遇到第一个"("为止;出栈的运算符依次存到list中(注意"("和")"不算运算符,但有优先级)遍历表达式a + (b + c) * d - e列出遍历过程中的状态1 list: a stack: 2 list: a stack: +3 list: a stack: +,(4 list: a,b stack: +,(5 list: a,b stack: +,(,+6 list: a,b,c stack: +,(,+7 list: a,b,c,+ stack: +8 list: a,b,c,+ stack: +,*9 list: a,b,c,+,d stack: +,*10 list: a,b,c,+,d,*,+ stack: -11 list: a,b,c,+,d,*,+,e stack: -12 list: a,b,c,+,d,*,+,e,- stack: list最后就是后序表达式然后遍历这个后序表达式,遇到非运算符则压栈,遇到运算符则出栈(2个元素出栈),并把计算的结果压栈,这样遍历完表达式的时候,堆栈中的结果就是最后的计算结果遍历list的后序表达式a,b,c,+,d,*,+,e,- 列出遍历过程中的状态1 list: b,c,+,d,*,+,e,- stack: a2 list: c,+,d,*,+,e,- stack: a,b3 list: +,d,*,+,e,- stack: a,b,c4 list: d,*,+,e,- stack: a,v1 //v1=b+c5 list: *,+,e,- stack: a,v1,d6 list: +,e,- stack: a,v2 //v2=v1*d7 list: e,- stack: v3 //v3=a+v28 list: - stack: v3,e9 list: stack: v4 //v4=v3-e 同意: qybao(阿宝) 的。 单向链表,删除所有最小元素 请教:通过文件选择框获取文件列表 JAVA生成exe文件 java连接sqlserver2000的问题 请教一个简单的接口实现的问题 (String) 四则运算公式的分析 Java.Big.Decimal类型转换问题? 各位高手指引一下! 中文问题 不知那里出错了 天生不笨请来取分 关于className及调用其方法的问题。有点晕了 防止程序重复启动
用两个栈(operate,data),一个用来存放操作符号(如:+ - * /)另一个用来存放要操作的数据
例:3+5*2-2
当按下3按钮时,data栈将数据3压入栈中.
当按下+号按钮时,先判断栈中有无"+"或"-",如果有则将data栈中前两个数据pop,并pop operate栈中的符号并加以计算,计算后从新压入data栈中operate栈将"+"压入栈中,
.....
当按下"*"或"/"时,判断operate中是否有"*""/",如果是,则将符号和数据弹出,计算,压入栈中,再将新按下的符号压入栈中
.....
.....
我觉得这个办法应该没问题吧?编译通过了
但运行是老是出错,
高人快来看看
import java.awt.*;
import java.util.*;public class Calculator extends Applet
{ public void init()
{
setLayout(new BorderLayout()); Panel p1=new Panel();
p1.setBackground(Color.gray);//设置p1的背景色
display=new ExpTextField("",30);
p1.add(display);
p1.add(new Button("清空"));
add("North",p1);
Panel p2=new Panel();
p2.setLayout(new GridLayout(3,6));//网格布局
p2.add(new Button("7"));
p2.add(new Button("8"));
p2.add(new Button("9"));
p2.add(new Button("("));
p2.add(new Button(")"));
p2.add(new Button("="));
p2.add(new Button("4"));
p2.add(new Button("5"));
p2.add(new Button("6"));
p2.add(new Button("."));
p2.add(new Button("+"));
p2.add(new Button("-"));
p2.add(new Button("1"));
p2.add(new Button("2"));
p2.add(new Button("3"));
p2.add(new Button("0"));
p2.add(new Button("*"));
p2.add(new Button("/"));
add("Center",p2);
}
public boolean action(Event e,Object a)//按钮事件的action方法
{
if(a instanceof String)
{
if(a.equals("清空"))//清空
{
display.setText("");
return true;
} display.setText(display.getText()+(String)a);
if(a.equals("="))//当用户按下=键开始计算
display.setText(EvaluateExpression.calculate(display.getText()));
return true;
}
else
return super.action(e,a);//如果事件没有处理,将事件传输到该类在继承体系中父类去处理
}
private ExpTextField display;
}
class ExpTextField extends TextField
{
public ExpTextField(String s,int n)
{
super(s,n);
}
public boolean keyDown(Event e,int key)
{
if(key==61)//=键
{
setText(getText()+"=");
setText(EvaluateExpression.calculate(getText()));
return true;
}
else if(key==27)//Esc键
{
setText("");
return true;
}
else if((key>=40)&&(key<=57)&&(key!=44)//数字或运算符
||(key==8)||(key==127)//Backspace键或delete键
||(key==Event.LEFT)||(key==Event.RIGHT)//左右键
||(key==Event.HOME)||(key==Event.END))//Home键或End键
return super.keyDown(e,key);
else //忽略其它键
return true;
}
}class EvaluateExpression //算符优先算法
{
public static String calculate(String exp)
{
char lastoptr='=';
char c;
char ch;
double d1;//操作数
double d2;//操作数
String opnd=" ";
String result;
Stack optrstack=new Stack();//运算符栈
Stack opndstack=new Stack();//操作数栈
optrstack.push(new Character('='));
try
{
for(int i=0;i<exp.length();i++)
{
c=exp.charAt(i);//输入的字符 if(Character.isDigit(c)||(c=='.'))//操作数
{
opnd=opnd+c;
}
else if((c=='+')||(c=='-')||(c=='*')||(c=='/')||(c=='(')||(c==')')||(c=='='))//运算符
{
if((c=='-')&&opnd.equals("")&&((lastoptr=='=')||(lastoptr=='(')))
c='@';//c为负号
if(!opnd.equals(""))
{
opndstack.push(new Double(opnd));//进操作数栈
opnd="";
}
while(getF(((Character)optrstack.peek()).charValue())>getG(c))//比较优先权
{
ch=((Character)optrstack.pop()).charValue();
if(ch=='@')//一个操作数的情况
{
d1=((Double)opndstack.pop()).doubleValue();
opndstack.push(new Double(-d1));
}
else//两个操作数的情况
{
d2=((Double)opndstack.pop()).doubleValue();
d1=((Double)opndstack.pop()).doubleValue();
opndstack.push(new Double(cal(d1,d2,ch)));
}
}
if(getF(((Character)optrstack.peek()).charValue())<getG(c))//比较优先权
{
optrstack.push(new Character(c));
lastoptr=c;
continue;
}
if(getF(((Character)optrstack.peek()).charValue())==getG(c))//比较优先权
{
optrstack.pop();
lastoptr=c;
continue;
}
}
else
return("ERROR");
}
result=((Double)opndstack.pop()).toString(); if((!optrstack.empty())||(!opndstack.empty()))
result="ERROR";
}
catch(NumberFormatException e)
{
result="ERROR";
}
catch(ArithmeticException e)
{
result="ERROR";
}
return result;
}
private static int getF(char c)//运算符栈顶元素优先函数
{
switch(c)
{
case'+':
case'-': return 2;
case'*':
case'/': return 4;
case'@': return 5;
case'(': return 0;
case')': return 6;
case'=': return 0;
default: return -1;
}
}
private static int getG(char c)//输入的运算符优先函数
{
switch(c)
{
case'+':
case'-': return 1;
case'*':
case'/': return 3;
case'@': return 6;
case'(': return 7;
case')': return 0;
case'=': return 0;
default: return -1;
}
} private static double cal(double d1,double d2,char c)
{
switch(c)
{
case'+': return(d1+d2);
case'-': return(d1-d2);
case'*': return(d1*d2);
case'/': return(d1/d2);
default: return -1;
}
}
}
比如a + (b + c) * d - e
转成a,b,c,+,d,*,+,e,-(具体转换你自己看数据结构的书吧,主要是自己定义好运算符的优先级,然后逐个压栈退栈等等)
例如:list(保存元素用),stack(运算符压栈出栈用)
1)运算符优先级 "(,)"大于"*,/,%"大于"+,-"
2)压栈出栈规则,当遍历到的运算符的优先级小于或等于栈顶运算符的优先级时,栈中运算符出栈,直到遇到栈中运算符的优先级比其小为止,然后将其压栈;遇到"("时直接压栈,遇到")"时栈中运算符出栈,直到遇到第一个"("为止;出栈的运算符依次存到list中(注意"("和")"不算运算符,但有优先级)
遍历表达式a + (b + c) * d - e
列出遍历过程中的状态
1 list: a stack:
2 list: a stack: +
3 list: a stack: +,(
4 list: a,b stack: +,(
5 list: a,b stack: +,(,+
6 list: a,b,c stack: +,(,+
7 list: a,b,c,+ stack: +
8 list: a,b,c,+ stack: +,*
9 list: a,b,c,+,d stack: +,*
10 list: a,b,c,+,d,*,+ stack: -
11 list: a,b,c,+,d,*,+,e stack: -
12 list: a,b,c,+,d,*,+,e,- stack:
list最后就是后序表达式
然后遍历这个后序表达式,遇到非运算符则压栈,遇到运算符则出栈(2个元素出栈),并把计算的结果压栈,这样遍历完表达式的时候,堆栈中的结果就是最后的计算结果
遍历list的后序表达式a,b,c,+,d,*,+,e,-
列出遍历过程中的状态
1 list: b,c,+,d,*,+,e,- stack: a
2 list: c,+,d,*,+,e,- stack: a,b
3 list: +,d,*,+,e,- stack: a,b,c
4 list: d,*,+,e,- stack: a,v1 //v1=b+c
5 list: *,+,e,- stack: a,v1,d
6 list: +,e,- stack: a,v2 //v2=v1*d
7 list: e,- stack: v3 //v3=a+v2
8 list: - stack: v3,e
9 list: stack: v4 //v4=v3-e