总结:
- 提取字符串要用char的值来逐一判断,java中使用ASC II值存储,例如通过一下表达式,可以直接输出ASC II值
(int)expression.charAt(index) < 48
- Java中字符以2个字节存储
Character ch = 'A';
System.out.println(Character.getNumericValue(ch)); // 直接将字符串转化为显示的数值 如0对应的就是0, A对应10
System.out.println((int)ch);
- 多次地方在循环条件中添加特殊判断,以防止溢出,且均放在if条件中最前面直接判断:
map.get(formula.peek()) != null; // 判断栈不为空,否则返回nulll
index < expression.length();// 防止溢出
formula.size() != 0 ;//判断不为空
遗留问题:
1)为什么字符串栈的的时候不能直接相等,例如以下在表达式可以存在,放到方法中是fales
formula.peek() == "*")
而是必须使用
formula.peek().equals('"*");
转换实现代码:
import java.util.*;
public class StackSufflix {
public static void main(String[] args) {
String exp = "1 + 2 * (9 - 4)";
String exp1 = "1 + 3";
String exp2 = "(3 + 8) * 2 - 1";
String exp3 = "(1 + 2 * (9 - 5) )";
List suffixtest = List.of("1","+","2","*","(","9","-","5",")");
System.out.println("Correct" +suffixtest);
SuffixExpression se = compile(exp3);
int result = se.execute();
System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗"));
// 以下是代码测试
char test = '1';
System.out.println("'1' asc ii is "+ (int)test); // 输出ASC II 值
String test1 = String.valueOf(test);
//System.out.println(test1.equals("1"));
//List list = expressionToList(exp);
//for(String s :list){
//System.out.println("提取符号后 "+s);
//}
}
static SuffixExpression compile(String ex) {
List element = new ArrayList<>(); // 存储表达式中元素符号
List midffix = new ArrayList<>(); // 存储中缀表达式
List suffix1 = new ArrayList<>(); // 存储后缀表达式
suffix1 = midTosuffix(ex);
return new SuffixExpression(suffix1);
}
// 中缀表达式转换为后缀表达式
static List midTosuffix (String expression){
List mid = expressionToList(expression);
System.out.println("mid is "+mid);
List suffix = new ArrayList<>();
Deque formula = new LinkedList<>();// 栈存储符号与计算方式
Map map = new HashMap<>();
map.put("+",1);
map.put("-",1);
map.put("*",2);
map.put("/",2);
map.put("(",3); // 相当于优先级最高,用于比较
//System.out.println("test map "+(map.get("+") == map.get("-")));
System.out.println("size "+formula.size());
List midtest1 = List.of("1","+","2","*","(","9","-","5",")");
List midtest2 = List.of("2","*","(","3","+","4",")");
List midtest3 = List.of("(","13","+","4",")","*","2");
for(String element: mid){
System.out.println("-----------------------");
System.out.println("后缀队列 "+suffix);
System.out.println("计算栈 "+formula+"栈顶为 "+ formula.peek());
//System.out.println("Formula "+(formula.peek() == "*")); // 为什么这里不能相等?
System.out.println("当前符号 "+element);
if(element.equals("+") || element.equals("-") || element.equals("*")|| element.equals("/")){
if(formula.size() != 0 && (formula.equals("+") || formula.peek().equals("-") || formula.peek().equals("*") || formula.peek().equals("/"))){
// 防止栈为空,euqals时会报错,加上一句对formula 栈的是否为空的检查
while (map.get(formula.peek()) != null && map.get(element) <= map.get(formula.peek())){ // 防止栈空取不到优先级,加限制条件
System.out.println("Its 符号比较场景 "+ formula.peek());
suffix.add(formula.pop());
System.out.println("优先级比较后栈 "+formula);
}
System.out.println("优先级高的添加后 再添加 "+element);
formula.push(element);
}else { // 栈为空的情况,直接入栈
System.out.println("栈为空 直接入栈 运算符号 "+element);
formula.push(element);
}
}else if(element.equals("(")){
System.out.println("Its (");
formula.push(element);
}else if(element.equals(")")){
System.out.println("Its )");
for(;;){
if(formula.peek().equals("(")) {
formula.pop(); // 遇到左括号直接删除
System.out.println("成功弹出 (");
break; // 退出循环
}
// 遇到不是左括号的,直接添加到队列中
System.out.println("弹出 符号(前的: "+formula.peek());
suffix.add(formula.pop());
}
}else {
System.out.println("Number "+ element+" added");
suffix.add(element);
}
}
System.out.println("------------------");
System.out.println("最终 队列:"+suffix);
System.out.println("最终 栈: "+formula+"长度 "+formula.size());
System.out.println("------------------");
while (formula.size() != 0){
suffix.add(formula.pop());
}
System.out.println("*********************");
System.out.println("最终 队列:"+suffix);
System.out.println("最终 栈: "+formula+"长度 "+formula.size());
System.out.println("*********************");
return suffix;
}
// 提取表达式中字符串与括号
static List expressionToList (String expression){
List cache = new ArrayList<>();
int index = 0;
label:for(;index < expression.length();){
if(expression.charAt(index) == ' '){
index = index + 1;
System.out.println("遇到空格");
System.out.println("空格 Index is "+index);
continue label;
}
if((int)expression.charAt(index) < 48 ||(int)expression.charAt(index) > 57 ){ // asc ii 0 对应48,9对应57
cache.add(String.valueOf(expression.charAt(index)));
System.out.println("Symbol is "+String.valueOf(expression.charAt(index)));
//System.out.println("Symbol is string ? "+String.valueOf(expression.charAt(index)).equals("+"));
index = index + 1;
}else {
String number = "";
while (index < expression.length() && (int)expression.charAt(index) > 47 && (int)expression.charAt(index) < 58){
number = number + String.valueOf(expression.charAt(index));
index = index + 1;
System.out.println("Number index is "+index);
}
cache.add(number);
System.out.println("number is "+number);
}
}
System.out.println("Cache "+cache);
return cache;
}
}
class SuffixExpression { // 需要写构造方法
public String suffixexp;
List suffix = new ArrayList<>(); // 存储后缀表达式
Deque cache = new LinkedList<>(); // 存储计算的
List suffixtest = List.of("1","2","3","+","4","*","+","5","-"); // ("1","2","3","+","4","*","5","-","+"); 结果是一样的
public SuffixExpression(List suffix){
this.suffix = suffix;
}
int execute() {
// 计算后缀的值
for(String s: suffix){
if(s.equals("*") | s.equals("/") | s.equals("+") | s.equals("-")){
String formula = s;
Integer first = cache.pop();// 倒数第一个
Integer second = cache.pop();// 倒数第二个
switch (formula){
case "*":
cache.push(second*first);
break;
case "/":
cache.push(second/first);
break;
case "+":
cache.push(second+first);
break;
case "-":
cache.push(second-first);
break;
}
//System.out.println("Its formula"+cache.peek());
}else {
Integer newvalue = Integer.valueOf(s);
cache.push(newvalue);
//System.out.println("Its number"+cache.peek());
}
}
//System.out.println(cache.peek()); // 打印最后的值,检查是否正确
Integer result1 = cache.pop(); // 返回最终结果
System.out.println("result1 is "+result1);
return result1;
}
}