一个简单计算器【解析表达式】

代码不长,就直接发咯

自己写的一个计算器

呵呵,1.0貌似有些简陋,仓促写的~~~~
卡片布局+字符串解析+相关计算设置
实现功能:即算即得模式,表达式模式
核心函数 String returnInner(String expression)
思想:将一个数学表达式以String形式输入,利用递归进行解析
      1.检测有无括号"("")"有则记录其位置,将括号内的字符串传入 得到
                       String temstring=括号前String+returnInner(括号内String)+括号后String
           递归调用returnInner(temstring)     最终得到一个无括号的表达式
     2.检测操作符个数,并用opt1,opt2记录
      3.根据符号数以及首个操作符,分别进行解析,递归调用
注:貌似数据结构课程要求是用 中缀变后缀,然后用两个栈分别存操作数和操作符,然后用出栈入栈计算~~~~米去试~~—-—b

行计算
    超麻烦,以后再试下~~~~~
    哪位大哥可以分析下时间复杂度么??暴汗~~~~~


calculator.java

 

貌似不大符合课程设计的要求

没用到堆栈,中缀变后缀之类的~~~

需要改进~~~》《

 

package project;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class Calculator {
 public static void main(String[] args)
    {
     EventQueue.invokeLater(new Runnable()//事件调度线程
     {
     public void run()
     {
      CalculatorFrame fram=new CalculatorFrame();
      fram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭
      fram.setVisible(true);//可见
     }
     });
    }

}
class CalculatorFrame extends JFrame
{
 public CalculatorFrame()
 {
  setTitle("计算器 V1.0" );
  setLocation(250,250);
  CalculatorPanel panel=new CalculatorPanel();
  add(panel);
   setSize(325,400);
  //pack();
 }
}
class CalculatorPanel extends JPanel
{
 private JButton display;
 private JPanel panel;
 private JPanel panel2;
 private double result;
 private String lastCommand;
 private boolean start;
 double str;
 private JPanel buttonpanel;
 private JPanel displaypanel;
 CardLayout card=new CardLayout();
 private JButton display1;
 private JButton display2;
 
 private boolean modenA=true;
 private boolean modenB=false;
 
 private double tempresult;
 private boolean first=true;
 
 private JButton turnzero;
 
 public CalculatorPanel()
 {
    setLayout(new BorderLayout());
 
    result=0;
    start=true;
  
    display=new JButton("0");
    display.setEnabled(false);
    add(display,BorderLayout.NORTH);
  
    displaypanel=new JPanel();
    displaypanel.setLayout(card);
    buttonpanel=new JPanel();
    buttonpanel.setLayout(new GridLayout(4,1));
  
    turnzero=new JButton("归零");
    display1=new JButton("即算即得模式");
    display2=new JButton("表达式模式");
    buttonpanel.add(turnzero);
    buttonpanel.add(display1);
    buttonpanel.add(display2);
    turnzero.addActionListener(new ActionListener()
    {
     public void actionPerformed(ActionEvent e)
     {
      display.setText("0");
      start=true;
     }
    });
  
 
  
    panel=new JPanel();
    panel.setLayout(new GridLayout(5,4));
  
    ActionListener append=new AppendAction();
    ActionListener answer=new AnswerAction();
  
    addButton("7",append);
    addButton("8",append);
    addButton("9",append);
    addButton("+",append);
    addButton("4",append);
    addButton("5",append);
    addButton("6",append);
    addButton("-",append);
    addButton("1",append);
    addButton("2",append);
    addButton("3",append);
    addButton("*",append);
    addButton("0",append);
    addButton(".",append);
  
    addButton("=",answer);
    addButton("/",append);
    addButton("(",append);
    addButton(")",append);
  
    panel2=new JPanel();
    panel2.setLayout(new GridLayout(5,4));
    ActionListener command=new CommandAction();
  
    addButton2("7",append);
    addButton2("8",append);
    addButton2("9",append);
    addButton2("+",command);
    addButton2("4",append);
    addButton2("5",append);
    addButton2("6",append);
    addButton2("-",command);
    addButton2("1",append);
    addButton2("2",append);
    addButton2("3",append);
    addButton2("*",command);
    addButton2("0",append);
    addButton2(".",append);
  
    addButton2("=",answer);
    addButton2("/",command);
  
  
    displaypanel.add("first",panel2);
    displaypanel.add("second",panel);
  
    display1.addActionListener(new ActionListener()
    {
     public void actionPerformed(ActionEvent e)
     {
      //card.previous(displaypanel);
     card.show(displaypanel, "first");
     modenB=false;
     modenA=true;
     }
    });
    display2.addActionListener(new ActionListener()
    {
     public void actionPerformed(ActionEvent e)
     {
      //card.next( displaypanel);
      card.show(displaypanel,"second");//注意参数,第一为总,显示的面板,第二为该面板下要显

示的名
      modenB=true;
      modenA=false;
     }
    });
  
    add(displaypanel,BorderLayout.CENTER);
    add(buttonpanel,BorderLayout.EAST);
  
  
  
 }
 private void addButton(String label,ActionListener listener)
 {
 
  Icon im=new ImageIcon(label+".jpg");
  JButton button=new JButton(label,im);
  button.addActionListener(listener);
  panel.add(button);
 }
 private void addButton2(String label,ActionListener listener)
 {
  Icon im=new ImageIcon(label+".jpg");
  JButton button=new JButton(label,im);
  button.addActionListener(listener);
  panel2.add(button);
 }
 
 //表达式模式下的两个监听
 private class AppendAction implements ActionListener
 {
  public void actionPerformed(ActionEvent event)
  {
   
   if(start)
     {
   display.setText(" ");
   start=false;
   first=true;
  
     }
     String input=event.getActionCommand();
        display.setText(display.getText()+input);
  
  }
 }
 private class AnswerAction implements ActionListener
 {
  public void actionPerformed(ActionEvent event)
  {
   try{
   if(modenB)
   {
       str=new CalExpression().calculate(display.getText());
       display.setText(ChtoString(str));
       start=true;
   }
   else if(modenA && first)
   {
    tempresult=Double.parseDouble(display.getText());
    calculate(Double.parseDouble(display.getText()));
    first=false;
   }
   else if(modenA && !first)
   {
    calculate(tempresult);
   }
   }catch(Exception e)
   {
    display.setText("0");
    start=true;
   }
  
  }
  public String ChtoString(double a)
  {
   Double s=new Double(a);
   return s.toString();
  }
 }
 private class CommandAction implements ActionListener
 {
  public void actionPerformed(ActionEvent event)
  {
     try{
   result=Double.parseDouble(display.getText());
      lastCommand=event.getActionCommand();
      display.setText(" ");
     }catch(Exception e)
     {
      display.setText("0");
      start=true;
     }
   
  }
 }
 //即算即得
 public void calculate(double x) throws Exception
 {
 
 
  if(lastCommand.equals("+"))  result +=x;
  else if(lastCommand.equals("-"))  result -=x;
     else if(lastCommand.equals("*"))   result *=x;
     else if(lastCommand.equals("/"))   result /=x;
  
  display.setText(""+result);
 
  start=true;
 }
 private class CalExpression{

//  整体运算
   public double calculate(String total) throws Exception
   {
    int position1=0;
    int position2=0;
  
    //分析表达式是否有括号
    Boolean had=false;
    for(int i=0;i<total.length();i++)
    {
     if(total.charAt(i)=='(')
      had=true;
    }
    if(total.length()<3)
     return 0;
  
    //查一下为什么indexof在此不能用~~~~谁知道的话告诉一声,下列代码错在哪里~~~

   //  用错这里  查了一小时菜查出错误
  
  
     if(had==true)//只需处理第一个括号,然后递归调用自身,有括号继续处理,没括号就得结果    

   {
     for(int i=0;i<total.length();i++)
     {
       if(total.charAt(i)=='(')
           {
             position1=i;
             continue;
           }
      if(total.charAt(i)==')')
          {
            position2=i;
            break;
          }
    }
     //这句重点,有点长,注意区域划分
   
     return  calculate(total.substring(0, position1).trim()   +  calculate( total.substring

(position1+1, position2).trim())  +   total.substring(position2+1, total.length()).trim()  )

   ;
   
   
      }
    else
     return returnInner(total);
   }
 
   //针对括号内的运算,即未带括号的表达式~~~有的话递归调用自身
   private double returnInner(String expression)
   {
    double result=0;
    int op1=0;
    int op2=0;
    char operator=' ';
    int count=0;
  
    //此循环用于获得前两个操作符的位置
      for(int i=0;i<expression.length();i++)
    {
     operator=expression.charAt(i);
     if(operator == 42 || operator == 43 || operator == 45  || operator == 47)
     {
          if(count==0)
          {
            op1=i;
            count++;
            continue;
          }
          if(count==1)
          {
             op2=i;
             break;
          }
     }
    }
  
   //判断第一个操作符,并用递归计算整个表达式~~~~~

   //即把未带括号的表达式拆成第一个数与其后面的表达式进行运算
   //这整个算法很经典~~~~呵呵~~有参考网上的解析~~~觉得这个最短最好用
   //当然,括号太多~~仔细辨清各个整体~~~复制到eclipse里排版下~~~

      operator=expression.charAt(op1);
     if (operator == '+')
     {
               result = Double.parseDouble(expression.substring(0, op1).trim());//获取第一个


               if (op2 > 0)
                   result += returnInner(expression.substring((op1 + 1), expression.length

()));//有两个以上操作符~~~递归
               else
                   result += Double.parseDouble(expression.substring(op1 + 1,

expression.length()).trim());//只有一个+号
        }
    else if (operator == '-') //同+运算
     {
               result = Double.parseDouble(expression.substring(0, op1).trim());
               if (op2> 0)
                   result -= returnInner(expression.substring((op1 + 1), expression.length

()));
               else
                   result -= Double.parseDouble(expression.substring(op1 + 1,

expression.length()).trim());
        }
    else if (operator == '*')
     {
     if (op2 > 0)//有两个以上操作符,先第一个数*第二个数  然后在与后面的字符组成一个表达式,

带入递归     有用空格特意局开整体
                  result = returnInner(   (Double.parseDouble(expression.substring(0,

op1).trim()) * Double.parseDouble( expression.substring((op1 + 1), op2)))   +

expression.substring(op2, expression.length()));
              else
                  result =(Double.parseDouble(expression.substring(0, op1).trim()) *

Double.parseDouble( expression.substring((op1 + 1), expression.length())));
      return result;
     }
    else if (operator == '/') //同*运算
     {
     if (op2 > 0)
                 result = returnInner(   (Double.parseDouble(expression.substring(0,

op1).trim()) / Double.parseDouble( expression.substring((op1 + 1), op2)))   +

expression.substring(op2, expression.length()));
             else
                 result =(Double.parseDouble(expression.substring(0, op1).trim()) /

Double.parseDouble( expression.substring((op1 + 1), expression.length())));
    }

      return result;
  }
 
 }
 
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值