先把中缀表达式转换为ArrayLIst的形式,
通过subString 和charAt,来扫描数字和字符,注意这里的索引i不是for循环,而是while
while(i小于字符串长度
:是符号就add并且i++,是数字就嵌套一个while
{(i+1的char不等于符号 :str +=char
}
下一位是符号就把str给add
然后i++
写个中缀转后缀的方法,
过程如下:
有两个栈,数栈和符号栈,
1,遇到数字直接加,
2.遇到符号做判断,当前的和栈顶(之后的和过去的)那个优先级更大,如果过去的(栈顶的)更大,那就把过去(栈顶)的加入数栈,再把当前的符号加到符号栈,如果当前的大就直接入符号栈
3如果遇到括号,左括号直接进符号栈,遇到右括号时,不停把符号栈的符号提取出来加到数栈里
直到遇到左括号为止,再把左括号出栈
4处理完123,把符号栈剩下的符号挨个加入到数栈
(虽然这里说明用的是栈,但是数栈既不需要peek,也不需要pop,只用往里面加,所以用Arraylist也是一样的)
原来:1((2+3)*4)-5,之后:1, 2, 3, +, 4, *, 5, -
转为后缀的Array list后,就进行运算
运算教程点这
package swt;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Stack;
public class JFpoland {
//式子是下面这个
public static String zhongshi = "1+((2+3)*4)-5";
static int g= 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
//String shizi = "3 4 + 5 * 6 - ";
ArrayList<String> a =noblanklist(zhongshi);
System.out.println(a);
ArrayList<String> reverse = zhuan(a);
System.out.println(reverse);
g = calculate(reverse);
//如果不想要弹窗就把下面这行注释掉
fr frame = new fr();
System.out.println(g);
/*
ArrayList<String> list = new ArrayList<>();
list = getlistString(shizi);
System.out.println(list);
try {
System.out.println(calculate(list));
}catch(Exception e) {
System.out.println(e.getMessage());
}
*/
}
//把字符串式子按空格分割成字符串数组再遍历存到Arraylist中
public static ArrayList<String> getlistString(String shizi){
ArrayList<String> list = new ArrayList<>();
String[] split = shizi.split(" ");
for(String ele:split) {
list.add(ele);
}
return list;
}
public static ArrayList<String> noblanklist (String shizi){
ArrayList<String> list = new ArrayList<>();
int i = 0;
String str = "";
char c;
do {
//如果c是个非数字,我需要加入到ls (c=shizi.charAt(i)) < 48 || (c=shizi.charAt(i)) >57
c = shizi.charAt(i);
if(shizi.substring(i,i+1).matches("\\D")) {
list.add("" + c);
i++;
}else {
str = "";
while(i < shizi.length() && shizi.substring(i,i+1).matches("\\d")) {
//限制是数字本身就是遇到符号就入栈的条件
str += c;
i++;
}
list.add(str);
}
}while(i < shizi.length());
return list;
}
public static int priority (int fuhao) {
if(fuhao == '*' || fuhao == '/') {
return 1;
}else if (fuhao == '+'||fuhao == '-') {
return 0;
}else {
return -1;
}
}
public static ArrayList<String> zhuan (ArrayList<String> slist) {
Stack<String> s1 = new Stack<String>();//符号
ArrayList<String> s2 = new ArrayList<>();//数字
for(String item:slist) {
if(item.matches("\\d+")) {
s2.add(item);
}else if (item.equals("(")) {
s1.push(item);
}else if (item.equals(")")) {
while(!s1.peek().equals("(")) {
s2.add(s1.pop());
}
s1.pop();
}else {
//当,当前符号的优先级小于之前加入的符号就把之前的提出来加到数栈
while(s1.size() != 0 && operation.getvalue(item) <= operation.getvalue(s1.peek())) {
s2.add(s1.pop());
}
s1.push(item);
}
}
while(s1.size() != 0) {
s2.add(s1.pop());
}
return s2;
}
public static int calculate(ArrayList<String> ls) {
Stack<String> stack = new Stack<String>();
for(String item:ls) {
if (item.matches("\\d+")) {
stack.push(item);
}else {
int num2 = Integer.parseInt(stack.pop());
int num1 = Integer.parseInt(stack.pop());
int res = 0;
if(item.equals("+")) {
res = num1 + num2;
}else if(item.equals("-")) {
res = num1 - num2;
}else if(item.equals("*")) {
res = num1 * num2;
}else if(item.equals("/")) {
res = num1 / num2;
}else {
throw new RuntimeException("运算有问题");
}
stack.push("" + res);
}
}
return Integer.parseInt(stack.pop());
}
}
class liste implements ActionListener {
fr now ;
public void set (fr a){
this.now = a;
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == now.list){
String zhongshi = now.list.getText();
ArrayList<String> a = JFpoland.noblanklist(zhongshi);
System.out.println(a);
ArrayList<String> reverse = JFpoland.zhuan(a);
System.out.println(reverse);
int g = JFpoland.calculate(reverse);
now.testshow.append("答案是"+g);
}
}
}
class fr extends JFrame{
public JTextField list ;
public JCheckBox check;
public JTextArea testshow;
liste listen;
public fr(){
init();
setVisible(true);
}
void init(){
setLayout(new FlowLayout());
list = new JTextField(20);
testshow = new JTextArea(9,20);
check = new JCheckBox("请输入乘号是*除是/的带括号无小数的加减乘除式子");
listen = new liste();
list.addActionListener(listen);
add(list);
add(check);
add(testshow);
pack();
listen.set(this);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
class operation {
public static int add = 1;
public static int sub = 1;
public static int mul = 2;
public static int div = 2;
public static int getvalue(String operation) {
int result = 0;
switch (operation) {
case "+": {
result = add;
break;
}
case "*": {
result = mul;
break;
}
case "/": {
result = div;
break;
}
case "-": {
result = sub;
break;
}
default:
System.out.println(operation);
System.out.println("不存在该运算符");
}
return result;
}
}