java 小小计算器 显现了括号功能

java 小小计算器 显现了括号功能

  (2011-04-30 10:46:58)
标签: 

it

分类: Java

学完java的数据结构后,又用java做了个简单计算器

目前没有添加按钮事件 只能从键盘输入

 

java <wbr>小小计算器 <wbr>显现了括号功能

 

核心算法是:

一:将中缀表达式转为后缀表达式:

 中缀表达式如1*2+(2-1), 其运算符一般出现在操作数之间, 因此称为中缀表 达式,也就是大家编程中写的表达式。编译系统不考虑表达式的优先级别, 只是对表达式从左到右进行扫描, 当遇到运算符时, 就把其前面的两 个操作数取出, 进行操作。为达到上述目的, 就要将中缀表达式进行改写,变 为后缀表达式如上面的表达式 1*2+(2-1), 就变为12*21-+; 后缀表达式中不含有括号, 且后缀表达式的操作数和中缀表达式的操作数排 列次序完全相同,只是运算符的 次序发生了改变。我们实现的时候,只需要用一个特定工作方式的数据结构 (栈),就可以实现。 其中stack  op;用来存放运算符栈。数组ans用来存放后缀表达式。 算法思想: 从左到右扫描中缀表达式,是操作数就放进数组ans的末尾。如果是运算符的话,分为下面3种情况:

 1)如果是‘(’直接压入op栈。

 2)如果是‘)’,依次从op栈弹出运算符加到数组ans的末尾,知道遇到'( ';

 3) 如果是非括号,比较扫描到的运算符,和op栈顶的运算符。如果扫描到的运算符优先级高于栈顶运算符则,把运算符压入栈。否则的话,就依次把栈中运算符弹出加到数组ans的末尾,直到遇到优先级低于扫描到的运算符或栈空,并且把扫描到的运算符压入栈中。 就这样依次扫描,知道结束为止。如果扫描结束,栈中还有元素,则依次弹出加到数组ans的末尾,就得到了后缀表达式。

二、后缀表达式的计算

 对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,丌需要括号,而丏操作符的优先级也丌再起作用了。您可以用如下算法对后缀表达式求值:
1. 初始化一个空堆栈
2. 从左到右读入后缀表达式
3. 如果字符是一个操作数,把它压入堆栈。
4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您丌能够弹出两个操作数,后缀表达式的诧法就丌正确。
5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。

 

下面是源码:

1、中缀转后缀类

package counter;

import java.util.Stack;


///算法/
MiddleToLast {

 
 public int prior(char op) {
  if (op == '+' || op == '-')
   return 1;
  if (op == '*' || op == '/')
   return 2;
  return 0;
 }

 
 public String middleToLast(String middle) {
  Stack op = new Stack();
  String ans = new String();
  char c[] = new char[50];
  int j = 0;
  for (int i = 0; i < middle.length(); i++) {
   char ch = middle.charAt(i);

   if (ch >= '0' && ch <= '9') {
    c[j] = ch;
    j++;
   }

   else {
    if (ch == '(') {
     op.push(Character.valueOf(ch));
    } else {
     if (ch == ')') {
      while (((Character) op.peek()).charValue() != '(') {
       c[j] = ((Character) op.peek()).charValue();
       j++;
       op.pop();
      }
      op.pop();
     } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
      if (op.empty())
       op.push(Character.valueOf(ch));
      else {
       if (prior(ch) > prior(((Character) op.peek())
         .charValue())) {
        op.push(Character.valueOf(ch));
       } else {
        while (!op.empty()
          && prior(ch) <= prior(((Character) op
            .peek()).charValue())) {
         c[j] = ((Character) op.peek()).charValue();
         j++;
         op.pop();
        }
        op.push(Character.valueOf(ch));
       }
      }
     }
    }
   }

  }

  while (!op.empty()) {
   c[j] = ((Character) op.peek()).charValue();
   j++;
   op.pop();
  }
  ans = String.valueOf(c, 0, j);

  return ans;
 }


}

 

2、计算后缀表达式

package counter;

import java.util.Stack;

public class Compute {
 private String s = new String();

 private MiddleToLast mtl = new MiddleToLast();

 public Compute() {
  this("");
 }

 public Compute(String s) {
  this.s = s;
 }

 public void setComputeString(String s) {
  this.s = s;
 }

 public String getComputeString() {
  return this.s;
 }

 public String getLastComputeString() {
  return this.mtl.middleToLast(this.s);
 }

 public int getResult() {

  int right = 0, left = 0, result = 0;

  Stack number = new Stack();
  number.push(Character.valueOf('='));
  char c;

  String last = this.mtl.middleToLast(this.s);

  for (int i = 0; i < last.length(); i++) {
   c = last.charAt(i);
   if (!isOperateSign(c))
    number.push(Integer.valueOf(c - 48));
   if (isOperateSign(c)) {
    right = ((Integer) number.pop()).intValue();
    left = ((Integer) number.pop()).intValue();
    result = this.ComputeResult(right, left, c);
    number.push(Integer.valueOf(result));
   }
  }

  return result;
 }

 public int ComputeResult(int right, int left, char op) {
  int result = 0;

  switch (op) {
  case '+':
   result = left + right;
   break;
  case '-':
   result = left - right;
   break;
  case '*':
   result = left * right;
   break;
  case '/':
   result = left / right;
   break;
  }
  return result;

 }

 public boolean isOperateSign(char c) {
  if (c == '+' || c == '-' || c == '/' || c == '*')
   return true;
  else
   return false;
 }

 

}

3、测试类

package counter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class test extends JFrame implements ActionListener {

 private JTextField jtf;

 private JButton jb;

 private String s = new String();

 private Compute cp;

 public test() {
  super("表达式计算");
  jtf = new JTextField();
  jtf.setSize(200, 30);
  jtf.setLocation(5, 5);
  jb = new JButton("计算");
  jb.addActionListener(this);
  jb.setSize(70, 30);
  jb.setLocation(5, 50);

  setLayout(null);
  add(jtf);
  add(jb);

  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(getToolkit().getScreenSize().width / 2 - 150, getToolkit()
    .getScreenSize().height / 2 - 150, 300, 300);
  setVisible(true);

 }

 public void actionPerformed(ActionEvent e) {
  this.s = jtf.getText();
  int result = this.count(s);
  s += " = " + result;

  this.jtf.setText(s);
 }

 public int count(String s) {
  int result = 0;
  cp = new Compute(s);

  result = cp.getResult();
  return result;
 }

 public static void main(String[] args) {
  new test();
 }
}

为了应付作业而编的,一个新手,请大家多多指教。/** * Title: Calculator * Description: * Copyright: Copyright (c) 2004 * Company: CUIT * Calculator.java * Created on 2004年10月13日, 下午2:35 * @author jacktom * @version 1.0*/import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Calculator extends JFrame implements ActionListener{ Operator oper; String a,result; int type; boolean flag1=false; boolean flag2=false; boolean judge=true; int count=0; JTextField text; JPanel jpanel[]; JPanel jpanel1; JButton jbutton[]; String name[]={"0",".","-/+","+","=","1","2","3","-",")","4","5","6","*","(","7","8","9","/","CE"}; //Construct the JFrame public Calculator() { oper=new Operator(); setSize(250,300); setVisible(true); //Overridden so we can exit when window is closed this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } }); Container con=getContentPane(); con.setLayout(new GridLayout(5,5)); text=new JTextField(12); text.setHorizontalAlignment(JTextField.RIGHT); jpanel1=new JPanel(); jpanel1.setLayout(new GridLayout(1,1)); jpanel1.add(text); jpanel=new JPanel[4]; for(int i=0;i<4;i++) { jpanel[i]=new JPanel(); jpanel[i].setLayout(new GridLayout(1,5)); } jbutton=new JButton[name.length]; //add button to panel for(int j=0;j=0;i--) { con.add(jpanel[i]); } } public void actionPerformed(ActionEvent e) { for(int i=0;i<10;i++) { if(e.getActionCommand().equals(String.valueOf(i))) if(flag1==false) { text.setText(String.valueOf(i)); flag1=true; } else { text.setText(text.getText()+i); } } if(e.getActionCommand().equals(".")) if(flag2==false&&count==0) { text.setText(text.getText()+"."); count++; flag1=true; } if(e.getActionCommand().equals("+")||e.getActionCommand().equals("-")||e.getActionCommand().equals("*")||e.getActionCommand().equals("/")) { if(judge) { a=text.getText(); oper.EvaluateExpression(a); } else judge=true; flag1=false; flag2=false; count=0; if(e.getActionCommand().equals("+")) { a="+"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("-")) { a="-"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("*")) { a="*"; oper.EvaluateExpression(a); } if(e.getActionCommand().equals("/")) { a="/"; oper.EvaluateExpression(a); } } if(e.getActionCommand().equals("=")) { if(judge) { a=text.getText(); oper.EvaluateExpression(a); } else judge=true; oper.EvaluateExpression("#"); text.setText(""); text.setText(String.valueOf(oper.CalculateResult())); flag1=false; flag2=false; count=0; } if(e.getSource()==jbutton[2]) { text.setText("-"+text.getText()); } if(e.getActionCommand().equals(")")) { a=text.getText(); oper.EvaluateExpression(a); oper.EvaluateExpression(")"); judge=false; } if(e.getActionCommand().equals("CE")) { text.setText(""); judge=true; count=0; flag1=false; flag2=false; oper=new Operator(); } if(e.getActionCommand().equals("(")) { oper.EvaluateExpression("("); } } /** * Main method * * @param args String[] */ public static void main(String args[]) { Calculator Cmain=new Calculator(); Cmain.pack(); }}/** * Operator.java * Description:用栈实现计算 * Created on 2004年10月13日, 下午3:35 * @author jacktom*/public class Operator{ StackY optr; //存放操作符 StackY opnd;//存放操作数 Puzhu p; boolean Mark; Operator() { p=new Puzhu(); optr=new StackY(); opnd=new StackY(); optr.push("#"); } public void EvaluateExpression(String s) { boolean mark=true; if(s=="+"||s=="-"||s=="*"||s=="/"||s=="("||s==")"||s=="#") { while(mark) { switch(p.Precede(optr.peek(),s)) { case -1: optr.push(s); mark=false; break; case 0: optr.pop(); mark=false; break; case 1: String theta=optr.pop(); String a =opnd.pop(); String b =opnd.pop(); if(a.indexOf(".",0)==-1&&b.indexOf(".",0)==-1) Mark=true; else Mark=false; double c=Double.valueOf(a).doubleValue(); double d=Double.valueOf(b).doubleValue(); double e=p.Operate(c,theta,d); String f=String.valueOf(e); if(theta=="/") Mark=false; if(Mark) opnd.push(f.substring(0,f.indexOf(".",0))); else opnd.push(f); break; } } } else opnd.push(s); } public String CalculateResult() { //double result=Double.valueOf(opnd.peek()).doubleValue(); return opnd.peek(); }}/** * Description:判断操作符的优先级并计算结果 * Created on 2004年10月13日, 下午4:00 * @author jacktom*/class Puzhu{ public Puzhu() {} public int Precede(String optr1,String optr2) { String[] A={"+","-","*","/","(",")","#"}; int[][] B={ {1,1,-1,-1,-1,1,1}, {1,1,-1,-1,-1,1,1}, {1,1,1,1,-1,1,1}, {1,1,1,1,-1,1,1}, {-1,-1,-1,-1,-1,0,2}, {1,1,1,1,2,1,1}, {-1,-1,-1,-1,-1,2,0}, }; int i=0,j=0,k; while(i<7) { if(A[i]==optr1) { break; } i++; } while(j<7) { if(A[j]==optr2) { break; } j++; } k=B[i][j]; return k; } public double Operate(double a,String oper,double b) { double c=0; if(oper=="+") c=a+b; if(oper=="-") c=b-a; if(oper=="*") c=a*b; if(oper=="/") c=b/a; return c; }}/** * StackY.java * Description:堆栈的基本操作实现 * Created on 2004年10月13日, 下午3:05 * @author jacktom*/public class StackY { private int maxSize; // size of stack array private String[] stackArray; private int top; // top of stack public StackY(int s) // constructor { maxSize = s; // set array size stackArray = new String[maxSize]; // create array top = -1; // no items yet }public StackY() // constructor { maxSize = 20; // set array size stackArray = new String[maxSize]; // create array top = -1; // no items yet } public void push(String j) // put item on top of stack { top++; stackArray[top] = j; // increment top, insert item } public String pop() // take item from top of stack { return stackArray[top--]; // access item, decrement top } public String peek() // peek at top of stack { return stackArray[top]; } public boolean isEmpty() // true if stack is empty { return (top == 0); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值