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; } }