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

本文介绍了一个使用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();
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值