java老师布置的作业,要我们编个计算器,而且要有括号功能。。。编的恶心哪,600多行代码,调试来调试去终于能用了,但是估计还有bug。
有一个bug我自己知道,但是不影响正常使用:可以存在前导零,就是说可以有0087这种数字,计算器会认为这就是87,。
下面是两个截图,左边是输入,右边是输出。
这个计算器的核心算法就是对左边的字符串进行处理,得出右边的结果,其中要考虑到括号匹配、负号、乘除优先级等等问题,这一个算法写了200行。
因为字符串比较短,最多就几十,所以我的算法比较暴力,没有考虑时间和空间复杂度,大量地对字符串进行遍历(不符合我这样一个ACMer严谨治学的精神啊。。。其实是因为有点懒)。
除此之外,计算器还能自动识别输入内容的合法性,如果不合法,你是输入不进去某些符号的
for example:如果你已经输入了8+9,此时你再按’)‘或者’(‘,计算器会没反应,你只有再写个’+‘或者把’9‘去掉才能输入’(‘。这个功能我是在输入的时候把每个位置的东西记录在了一个F[][]二维数组里,每次输入一个键,判断一下。
另比如你当前的式子不构成一个完整的表达式,按回车或者’=‘是无效的,你可以按’Backspace‘回去一点点修改,但是不支持跳着改,只能改上一个(本人能力和精力实在有限,要是加上跳着改,还要把左右箭头加进去,太麻烦)。
这个计算器支持鼠标点按钮和键盘输入,按’=‘或者’回车‘可以出结果,按’c‘可以清零。
还有一个让我要抓狂的事情!!!!因为是初学者,不咋会java,一开始还不知道字符串和double之间相互转化的算法系统早就给弄好了,我还自己编了change_to_double()和change_to_string()两个函数,写了几百行代码,调试这俩函数调了半天也没弄好,然后我知道可以用系统现成的函数的时候,简直要崩溃。。。
下面是double和string互相转化的实现方式。
string转double:
double a;
string ls="1.23"
a=Double.parseDouble(ls);
然后a就变成了double型的1.23。
double转string:两种方法(不知道区别是啥,都能用把)
方法1:直接在s后面+a(我觉得这个写起来简单)
String s="";
double a=1.23
s=s+a;
方法2:用String.valueOf(double);
String s="";
double a=1.23;
s==s.valueOf(a);
下面是我实现的代码。有些地方有注释。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Calculator extends JFrame {
static char A[]={'0','1','2','3','4','5','6','7','8','9'};
// static double k[]={0.1,0.001,0.0001,0.00001,0.000001,0.0000001};//什么破java软件,这个东西放到别的地方都报错
private JTextField textField1;
private JButton b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,
BACK,C,jia,jian,cheng,chu,deng,dian,zuok,youk;
public Calculator(){
super("计算器");
Container container=getContentPane();
// container.setLayout(new FlowLayout());
container.setLayout(null);
//文本框
textField1=new JTextField("");
textField1=new JTextField(35);
textField1.setBounds(20, 20, 290, 30);
container.add(textField1);
//各种按钮
BACK=new JButton("Backspace");
BACK.setBounds(20, 60, 110, 40);
container.add(BACK);
C=new JButton("C");
C.setBounds(140, 60, 50, 40);
container.add(C);
zuok=new JButton("(");
zuok.setBounds(200, 60, 50, 40);
container.add(zuok);
youk=new JButton(")");
youk.setBounds(260, 60, 50, 40);
container.add(youk);
jia=new JButton("+");
jia.setBounds(200, 110, 50, 40);
container.add(jia);
jian=new JButton("-");
jian.setBounds(260, 110, 50, 40);
container.add(jian);
cheng=new JButton("*");
cheng.setBounds(200, 160, 50, 40);
container.add(cheng);
chu=new JButton("/");
chu.setBounds(260, 160, 50, 40);
container.add(chu);
dian=new JButton(".");
dian.setBounds(140, 260, 50, 40);
container.add(dian);
deng=new JButton("=");
deng.setBounds(200, 210, 110, 90);
container.add(deng);
b0=new JButton("0");
b0.setBounds(20, 260, 110, 40);
container.add(b0);
b1=new JButton("1");
b1.setBounds(20, 210, 50, 40);
container.add(b1);
b2=new JButton("2");
b2.setBounds(80, 210, 50, 40);
container.add(b2);
b3=new JButton("3");
b3.setBounds(140, 210, 50, 40);
container.add(b3);
b4=new JButton("4");
b4.setBounds(20, 160, 50, 40);
container.add(b4);
b5=new JButton("5");
b5.setBounds(80, 160, 50, 40);
container.add(b5);
b6=new JButton("6");
b6.setBounds(140, 160, 50, 40);
container.add(b6);
b7=new JButton("7");
b7.setBounds(20, 110, 50, 40);
container.add(b7);
b8=new JButton("8");
b8.setBounds(80, 110, 50, 40);
container.add(b8);
b9=new JButton("9");
b9.setBounds(140, 110, 50, 40);
container.add(b9);
buttonjudge judge=new buttonjudge();
b1.addActionListener(judge);
b2.addActionListener(judge);
b3.addActionListener(judge);
b4.addActionListener(judge);
b5.addActionListener(judge);
b6.addActionListener(judge);
b7.addActionListener(judge);
b8.addActionListener(judge);
b9.addActionListener(judge);
b0.addActionListener(judge);
jia.addActionListener(judge);
jian.addActionListener(judge);
cheng.addActionListener(judge);
chu.addActionListener(judge);
zuok.addActionListener(judge);
youk.addActionListener(judge);
dian.addActionListener(judge);
BACK.addActionListener(judge);
C.addActionListener(judge);
deng.addActionListener(judge);
//键盘
keyboard KEY=new keyboard();
b0.addKeyListener(KEY);
b1.addKeyListener(KEY);
b2.addKeyListener(KEY);
b3.addKeyListener(KEY);
b4.addKeyListener(KEY);
b5.addKeyListener(KEY);
b6.addKeyListener(KEY);
b7.addKeyListener(KEY);
b8.addKeyListener(KEY);
b9.addKeyListener(KEY);
b0.addKeyListener(KEY);
jia.addKeyListener(KEY);
jian.addKeyListener(KEY);
cheng.addKeyListener(KEY);
chu.addKeyListener(KEY);
zuok.addKeyListener(KEY);
youk.addKeyListener(KEY);
dian.addKeyListener(KEY);
BACK.addKeyListener(KEY);
C.addKeyListener(KEY);
deng.addKeyListener(KEY);
setSize(340,350);
setVisible(true);
}
public static void main(String[] args) {
Calculator application=new Calculator();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
int ct=0;
int F[][]=new int[100][10];
public void memsetF(){
/*F[i][0]表示存在否,F[i][1]表示当前需要匹配的右括号个数,
F[i][2]表示当前是否有小数点存在,1为有,0为没有,
F[i][3]表示加乘除为1,普通数字为2,左括号为3,右括号为4,小数点为5,减号为6,无为0
*/
for(int i=0;i<100;i++){
for(int j=0;j<10;j++){
F[i][j]=0;
}
}
}
public class keyboard implements KeyListener{//键盘事件处理
public void keyTyped(KeyEvent e) {
String S=textField1.getText();
if(e.getKeyChar()=='*'||e.getKeyChar()=='/'||e.getKeyChar()=='+'){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][3]!=1&&F[ct-1][3]!=5&&F[ct-1][3]!=3) {
if(e.getKeyChar()=='+')textField1.setText(S+'+');
else if(e.getKeyChar()=='*')textField1.setText(S+'*');
else if(e.getKeyChar()=='/')textField1.setText(S+'/');
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][3]=1;
ct++;
}
}
else if(e.getKeyChar()=='='){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][1]==0&&F[ct-1][3]!=1&&F[ct-1][3]!=3&&F[ct-1][3]!=5&&F[ct-1][3]!=6){
textField1.setText(CCLT(S));
}
}
else {
if(e.getKeyChar()=='-'){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][3]!=1&&F[ct-1][3]!=5) {
textField1.setText(S+'-');
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][3]=6;
ct++;
}
if(ct==0){
textField1.setText(S+'-');
F[ct][0]=1;
F[ct][3]=6;
ct++;
}
}
else if(e.getKeyChar()=='('){
if((ct>0&&F[ct-1][3]!=5&&F[ct-1][3]!=4&&F[ct-1][3]!=2)||ct==0){
textField1.setText(S+'(');
F[ct][0]=1;
if(ct==0){
F[ct][1]=1;
}
if(ct>0){
F[ct][1]=F[ct-1][1]+1;
}
F[ct][3]=3;
ct++;
}
}
else if(e.getKeyChar()==')'){
if(ct>0&&(F[ct-1][3]==2||F[ct-1][3]==4)&&F[ct-1][1]>0){
textField1.setText(S+')');
F[ct][0]=1;
F[ct][1]=F[ct-1][1]-1;
F[ct][3]=4;
ct++;
}
}
else if(e.getKeyChar()=='.'){
if(ct>0&&F[ct-1][2]==0&&F[ct-1][3]==2){
textField1.setText(S+'.');
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][2]=1;
F[ct][3]=5;
ct++;
}
}
else if(e.getKeyChar()>='0'&&e.getKeyChar()<='9'){
if(ct==0){
textField1.setText(S+e.getKeyChar());
F[ct][0]=1;
F[ct][3]=2;
ct++;
}
else if(F[ct-1][3]!=4){
textField1.setText(S+e.getKeyChar());
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][2]=F[ct-1][2];
F[ct][3]=2;
ct++;
}
}
}
}
public void keyPressed(KeyEvent e) {
String S=textField1.getText();
if(e.getKeyCode()==KeyEvent.VK_C){
textField1.setText("");
ct=0;
memsetF();
}
else if(e.getKeyCode()==KeyEvent.VK_BACK_SPACE){
if(ct>0){
ct--;
textField1.setText(S.substring(0,S.length()-1));
F[ct][0]=0;F[ct][1]=0;F[ct][2]=0;F[ct][3]=0;
}
}
else if(e.getKeyCode()==KeyEvent.VK_ENTER){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][1]==0&&F[ct-1][3]!=1&&F[ct-1][3]!=3&&F[ct-1][3]!=5&&F[ct-1][3]!=6){
textField1.setText(CCLT(S));
}
}
}
public void keyReleased(KeyEvent e) {}
}
private class buttonjudge implements ActionListener{//按钮事件处理
public void actionPerformed(ActionEvent event){
String S=textField1.getText();
String curs=event.getActionCommand();
if(curs=="C"){
textField1.setText("");
ct=0;
memsetF();
}
else if(curs=="Backspace"){
if(ct>0){
ct--;
textField1.setText(S.substring(0,S.length()-1));
F[ct][0]=0;F[ct][1]=0;F[ct][2]=0;F[ct][3]=0;
}
}
else if(curs=="="){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][1]==0&&F[ct-1][3]!=1&&F[ct-1][3]!=3&&F[ct-1][3]!=5&&F[ct-1][3]!=6){
textField1.setText(CCLT(S));
}
}
else {
if(curs=="+"||curs=="*"||curs=="/"){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][3]!=1&&F[ct-1][3]!=5&&F[ct-1][3]!=3) {
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][3]=1;
ct++;
}
}
else if(curs=="-"){
if(ct>0&&F[ct-1][0]==1&&F[ct-1][3]!=1&&F[ct-1][3]!=5) {
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][3]=6;
ct++;
}
if(ct==0){
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][3]=6;
ct++;
}
}
else if(curs=="("){
if((ct>0&&F[ct-1][3]!=5&&F[ct-1][3]!=4&&F[ct-1][3]!=2)||ct==0){
textField1.setText(S+curs);
F[ct][0]=1;
if(ct==0){
F[ct][1]=1;
}
if(ct>0){
F[ct][1]=F[ct-1][1]+1;
}
F[ct][3]=3;
ct++;
}
}
else if(curs==")"){
if(ct>0&&(F[ct-1][3]==2||F[ct-1][3]==4)&&F[ct-1][1]>0){
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][1]=F[ct-1][1]-1;
F[ct][3]=4;
ct++;
}
}
else if(curs=="."){
if(ct>0&&F[ct-1][2]==0&&F[ct-1][3]==2){
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][2]=1;
F[ct][3]=5;
ct++;
}
}
else {
if(ct==0){
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][3]=2;
ct++;
}
else if(F[ct-1][3]!=4){
textField1.setText(S+curs);
F[ct][0]=1;
F[ct][1]=F[ct-1][1];
F[ct][2]=F[ct-1][2];
F[ct][3]=2;
ct++;
}
}
}
}
}
// public static double change_to_double(String s){//
// int isfushu=0;
// if(s.charAt(0)=='#'||s.charAt(0)=='-'){
// isfushu=1;
// s=s.substring(1, s.length());
// }
// double ans=0;
// int point=0,findedp=0;
// for(int i=0;i<s.length();i++){
// if(s.charAt(i)=='.'){
// findedp=1;
// point=i;
// break;
// }
// }
// if(findedp==0){
// double fk=1;
// for(int i=0;i<s.length();i++){
// ans+=(s.charAt(s.length()-i-1)-'0')*fk;
// fk*=10;
// }
// }
// else if(findedp==1){
// int fk=1;
// for(int i=0;i<point;i++){
// ans+=(s.charAt(point-i-1)-'0')*fk;
// fk*=10;
// }
// fk=1;
//
// for(int i=point+1;i<s.length();i++){
// ans+=(s.charAt(i)-'0')*k[fk];
// fk++;
// if(fk>6)break;
// }
// }
// if(isfushu==0)return ans;
// else if(isfushu==1)return ans*(-1);
// return 0;
// }
//
// public static String change_to_String(double a){//
// int isfushu=0;
// if(a<0)isfushu=1;
// String s="";
// int havep=0;
// if(a-(int)(a)!=0)havep=1;
// if(havep==0){
// System.out.println(a);
// while(1==1){
// int b=(int) (a%10);
// s=A[b-0]+s;
// a/=10;
// if(a==0)break;
// }
// }
// else if(havep==1){
// int c=(int)(a);
// System.out.println(c);
// while(1==1){
// int b=(int) (c%10);
// s=A[b]+s;
// System.out.println(s);
// c/=10;
// if(c==0)break;
// }
// s+='.';
// System.out.println(s);
// double d=a-(int)(a);
// while(1==1){
// int x=(int)(d*10);
// s=s+A[x];
// System.out.println(s);
// d*=10;
// if(d==0||s.length()>6)break;
// }
// }
// if(isfushu==0)return s;
// else return '#'+s;
//
// }
public String CCLT(String s){
//把“--”换为“-0+”
int qq=-1;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='-'&&s.charAt(i+1)=='-'){
qq=i;
}
}
if(qq!=-1){
return CCLT(s.substring(0, qq)+"-0+"+s.substring(qq+2, s.length()));
}
int flag=0;
for(int i=0;i<s.length();i++){//判断有没有括号
if(s.charAt(i)=='('){
flag=1;
break;
}
}
int l=0,r=0,findedl=0,findedr=0;
if(flag==1){//有括号
int kuohaonum[]=new int[100];
for(int i=0;i<100;i++)kuohaonum[i]=0;
if(s.charAt(0)=='('){
kuohaonum[0]=1;
findedl=1;
l=0;
}
for(int i=1;i<s.length();i++){
if(findedl==1&&findedr==1)break;
if(s.charAt(i)=='('){
kuohaonum[i]=kuohaonum[i-1]+1;
if(kuohaonum[i]==1&&findedl==0){l=i;findedl=1;}
}
else if(s.charAt(i)==')'){
kuohaonum[i]=kuohaonum[i-1]-1;
if(kuohaonum[i]==0&&findedr==0){r=i;findedr=1;}
}
else kuohaonum[i]=kuohaonum[i-1];
}
String Final=s.substring(0,l)+CCLT(s.substring(l+1, r));
if(r+1>=s.length()){
return CCLT(Final);
}
else return CCLT(Final+s.substring(r+1,s.length() ));
}
else if(flag==0){//无括号
int p=0,priority=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='*'||s.charAt(i)=='/'){
p=i;
priority=1;
break;
}
}
if(priority==1){//有乘除时
String n="";
String ls="";
String rs="";
int havejian=0;//向左走遇到减号
int havenum=0;//向右走遇到数字
for(int i=p-1;i>=0;i--){
if(s.charAt(i)=='-'||s.charAt(i)=='.'||(s.charAt(i)>='0'&&s.charAt(i)<='9')){
if(s.charAt(i)=='-')havejian=1;
if(havejian==1&&((s.charAt(i)>='0'&&s.charAt(i)<='9'))){
break;
}
ls=s.charAt(i)+ls;
}
else break;
}
if(s.charAt(p+1)=='-')rs+='-';//#代表相反数
if(s.charAt(p+1)>='0'&&s.charAt(p+1)<='9'){
rs+=s.charAt(p+1);
}
for(int i=p+2;i<s.length();i++){
if((s.charAt(i)>='0'&&s.charAt(i)<='9')||s.charAt(i)=='.'){
rs+=s.charAt(i);
}
else break;
}
int len_of_l=ls.length();
int len_of_r=rs.length();
ls=CCLT(ls);
rs=CCLT(rs);
double a,b;
a=Double.parseDouble(ls);
b=Double.parseDouble(rs);
if(s.charAt(p)=='*'){
n=n+(a*b);
}
else if(s.charAt(p)=='/'){
n=n+(a/b);
}
String Final="";
Final=s.substring(0, p-len_of_l)+n;
if(p+len_of_r+1>s.length()){
return CCLT(Final);
}
else{
return CCLT(s.substring(0, p-len_of_l)+
n+
s.substring(p+len_of_r+1, s.length()));
}
}
else if(priority==0){//没有乘除优先级
p=0;
if(s.charAt(0)=='-'){
for(int i=1;i<s.length();i++){
if(s.charAt(i)=='-'||s.charAt(i)=='+'){
p=i;
break;
}
}
}
else if(s.charAt(0)!='-'){
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='-'||s.charAt(i)=='+'){
p=i;
break;
}
}
}
if(p==0){//出答案
String finalans="";
return finalans+Double.parseDouble(s);
}
//计算加减
String n="";
String ls="";
String rs="";
int havejian=0;//向左走遇到减号
int havenum=0;//向右走遇到数字
for(int i=p-1;i>=0;i--){
if(s.charAt(i)=='-'||s.charAt(i)=='.'||(s.charAt(i)>='0'&&s.charAt(i)<='9')){
if(s.charAt(i)=='-')havejian=1;
if(havejian==1&&((s.charAt(i)>='0'&&s.charAt(i)<='9'))){
break;
}
ls=s.charAt(i)+ls;
}
else break;
}
if(s.charAt(p+1)=='-')rs+='-';//#代表相反数
if(s.charAt(p+1)>='0'&&s.charAt(p+1)<='9'){
rs+=s.charAt(p+1);
}
for(int i=p+2;i<s.length();i++){
if((s.charAt(i)>='0'&&s.charAt(i)<='9')||s.charAt(i)=='.'){
rs+=s.charAt(i);
}
else break;
}
int len_of_l=ls.length();
int len_of_r=rs.length();
ls=CCLT(ls);
rs=CCLT(rs);
double a,b;
a=Double.parseDouble(ls);
b=Double.parseDouble(rs);
if(s.charAt(p)=='+'){
n=n+(a+b);
}
else if(s.charAt(p)=='-'){
n=n+(a-b);
}
String Final="";
Final=s.substring(0, p-len_of_l)+n;
if(p+len_of_r+1>s.length()){
return CCLT(Final);
}
else{
return CCLT(s.substring(0, p-len_of_l)+
n+
s.substring(p+len_of_r+1, s.length()));
}
}
}
return null;
}
}
JAVA计算器(有无限加括号功能)+string与double互相转化
原文地址:http://blog.csdn.net/qdbszsj/article/details/45562297