算法

来源:互联网 发布:武汉软件行业协会 编辑:程序博客网 时间:2024/06/04 18:11

核心算法是:
一:将中缀表达式转为后缀表达式:
中缀表达式如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();
}
}

0 0