Java 用逻辑实现调车场
因此,我试图实现一个分流场来处理逻辑,我认为这很容易,直到我遇到了为物质条件(->)和双条件()语句设置优先级的问题,因为它们需要表示为字符串而不是字符。我需要能够读取带有语句的文件,例如Java 用逻辑实现调车场,java,enums,case,discrete-mathematics,shunting-yard,Java,Enums,Case,Discrete Mathematics,Shunting Yard,因此,我试图实现一个分流场来处理逻辑,我认为这很容易,直到我遇到了为物质条件(->)和双条件()语句设置优先级的问题,因为它们需要表示为字符串而不是字符。我需要能够读取带有语句的文件,例如(a | B)->!C(意思是:(A或B)不表示C)并将其翻译成后缀符号。我一直在第115行得到一个NullPointerException,我实际上不知道为什么,我可以只使用char值设置一个case吗?或者我需要找到另一种为符号设置优先级的方法吗。这是我的密码 import java.io.IOExcept
(a | B)->!C
(意思是:(A或B)不表示C)并将其翻译成后缀符号。我一直在第115行得到一个NullPointerException,我实际上不知道为什么,我可以只使用char值设置一个case吗?或者我需要找到另一种为符号设置优先级的方法吗。这是我的密码
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.Scanner;
import java.io.File;
import java.util.ArrayList;
import java.io.Reader;
public class ShuntingYard
{
public static ArrayList<String> symbols = new ArrayList<String>();
public static ArrayList<String> letters = new ArrayList<String>();
public static String path = "";
public static void main(String args[])
{
ShuntingYard sy = new ShuntingYard();
//Scans in File.
Scanner scan = new Scanner(System.in);
String prompt = "Please specify the file path.\n Use the form: D:\\DiscreteMath\\inputFile.txt";
System.out.println(prompt);
path = scan.next();
File file = new File(path);
String infix = "";
try{
scan = new Scanner(file);
infix = scan.nextLine();
}
catch(IOException e)
{
System.err.println(" No file");
}
// calls postfix function
String postfix = sy.postfix(infix);
System.out.println("\nPostfix expression : " + postfix);
String al = "A,B,C,D,E,";
}
public enum Precedence
{
//configure precedence of symbols and operands.
lparen(0), rparen(1), not(2), and(3), or(4), mc(5), bc(6), eos(7), operand(8);
private int index;
Precedence(int index)
{
this.index = index;
}
public int getIndex()
{
return index;
}
}
private static final int[] isp = {0,19,12,12,13,13,0};
private static final int[] icp = {20,19,12,12,13,13,0};
private static final String[] operators = {"{","}","!","&","|","->","<->"," "};
//initializes stack
private Precedence[] stack;
private int top;
private Precedence pop()
{
return stack[top--];
}
private void push(Precedence ele)
{
stack[++top] = ele;
}
//Sets Precedence of symbols.
public Precedence getToken(String symbol)
{
switch(symbol)
{
case "(" : return Precedence.lparen;
case ")" : return Precedence.rparen;
case "!" : return Precedence.not;
case "&" : return Precedence.and;
case "|" : return Precedence.or;
case "->" : return Precedence.mc;
case "<->" : return Precedence.bc;
case " " : return Precedence.eos;
default : return Precedence.operand;
}
}
//Changes infix to postfix notation then returns a string value.
public String postfix(String infix)
{
String postfix = "";
top = 0;
stack = new Precedence[infix.length()];
Precedence token;
for(int i = 0; i<infix.length(); i++)
{
token = getToken(Character.toString(infix.charAt(i)));
if(token == Precedence.operand)
{
postfix = postfix + infix.charAt(i);
}
else if(token == Precedence.rparen)
{
while(stack[top] != Precedence.lparen)
{
postfix = postfix + operators[pop().getIndex()];
}
pop();
}
else
{
while(isp[stack[top].getIndex()] >= icp[token.getIndex()])
{
postfix = postfix + operators[pop().getIndex()];
}
push(token);
}
}
while((token = pop()) != Precedence.eos)
{
postfix = postfix + operators[token.getIndex()];
}
return postfix;
}
import java.io.IOException;
导入java.io.FileReader;
导入java.io.BufferedReader;
导入java.util.Scanner;
导入java.io.File;
导入java.util.ArrayList;
导入java.io.Reader;
公共级调车场
{
公共静态ArrayList符号=新ArrayList();
public static ArrayList letters=new ArrayList();
公共静态字符串路径=”;
公共静态void main(字符串参数[])
{
调车场sy=新调车场();
//扫描文件。
扫描仪扫描=新扫描仪(System.in);
String prompt=“请指定文件路径。\n使用以下格式:D:\\DiscreteMath\\inputFile.txt”;
System.out.println(提示);
path=scan.next();
文件=新文件(路径);
字符串中缀=”;
试一试{
扫描=新扫描仪(文件);
中缀=scan.nextLine();
}
捕获(IOE异常)
{
System.err.println(“无文件”);
}
//调用后缀函数
字符串后缀=sy.postfix(中缀);
System.out.println(“\n后缀表达式:“+postfix”);
字符串al=“A、B、C、D、E”;
}
公共枚举优先级
{
//配置符号和操作数的优先级。
lparen(0)、rparen(1)、not(2)和(3)或(4)、mc(5)、bc(6)、eos(7)、操作数(8);
私有整数索引;
优先级(整数索引)
{
这个指数=指数;
}
public int getIndex()
{
收益指数;
}
}
私有静态final int[]isp={0,19,12,12,13,13,0};
私有静态final int[]icp={20,19,12,12,13,13,0};
私有静态最终字符串[]运算符={{{,“}”,“!”,“&”,“|”,“->,”“,”“,”“};
//初始化堆栈
私有优先级[]堆栈;
私人int top;
私有优先权
{
返回堆栈[top--];
}
专用无效推送(优先ele)
{
堆栈[++top]=ele;
}
//设置符号的优先级。
公共优先级getToken(字符串符号)
{
开关(符号)
{
大小写“(”:返回priority.lparen;
大小写“)”:返回priority.rparen;
大小写“!”:返回优先级。否;
大小写“&”:返回优先级。和;
大小写“|”:返回优先级。或;
大小写“->”:返回priority.mc;
案例“”:return priority.bc;
案例“”:返回priority.eos;
默认值:返回优先级。操作数;
}
}
//将中缀更改为后缀符号,然后返回字符串值。
公共字符串后缀(字符串中缀)
{
字符串后缀=”;
top=0;
堆栈=新优先级[infix.length()];
优先标记;
对于(int i=0;i=icp[token.getIndex()])
{
后缀=后缀+运算符[pop().getIndex()];
}
推送(令牌);
}
}
while((token=pop())!=priority.eos)
{
后缀=后缀+运算符[token.getIndex()];
}
返回后缀;
}
}问题在于您没有检查空堆栈。如果在两个地方添加空堆栈检查,代码可以工作
import java.util.ArrayList;
import java.util.Arrays;
public class ShuntingYard
{
public static ArrayList<String> symbols = new ArrayList<String>();
public static ArrayList<String> letters = new ArrayList<String>();
public static String path = "";
public static void main(String args[])
{
ShuntingYard sy = new ShuntingYard();
//Scans in File.
// Scanner scan = new Scanner(System.in);
// String prompt = "Please specify the file path.\n Use the form: D:\\DiscreteMath\\inputFile.txt";
// System.out.println(prompt);
// path = scan.next();
// File file = new File(path);
String infix = "(A|B)&C"; // String infix = "(A|B) -> !C";
// try{
//
// scan = new Scanner(file);
// infix = scan.nextLine();
//
// }
// catch(IOException e)
// {
// System.err.println(" No file");
// }
// calls postfix function
String postfix = sy.postfix(infix);
System.out.println("\nPostfix expression : " + postfix);
String al = "A,B,C,D,E,";
// line 38
}
public enum Precedence
{
//configure precedence of symbols and operands.
lparen(0), rparen(1), not(2), and(3), or(4), mc(5), bc(6), eos(7), operand(8);
private int index;
Precedence(int index)
{
this.index = index;
}
public int getIndex()
{
return index;
}
}
private static final int[] isp = {0,19,12,12,13,13,0};
private static final int[] icp = {20,19,12,12,13,13,0};
private static final String[] operators = {"{","}","!","&","|","->","<->"," "};
//initializes stack
private Precedence[] stack;
private int top;
private Precedence pop()
{
return stack[top--];
}
private void push(Precedence ele)
{
stack[++top] = ele;
}
//Sets Precedence of symbols.
public Precedence getToken(String symbol)
{
switch(symbol)
{
case "(" : return Precedence.lparen;
case ")" : return Precedence.rparen;
case "!" : return Precedence.not;
case "&" : return Precedence.and;
case "|" : return Precedence.or;
case "->" : return Precedence.mc;
case "<->" : return Precedence.bc;
case " " : return Precedence.eos;
default : return Precedence.operand;
}
}
//Changes infix to postfix notation then returns a string value.
public String postfix(String infix)
{
String postfix = "";
top = -1;
stack = new Precedence[infix.length()];
Precedence token;
for(int i = 0; i<infix.length(); i++)
{
token = getToken(Character.toString(infix.charAt(i)));
System.out.println("Token "+ infix.charAt(i) + " " + token);
if(token == Precedence.operand)
{
postfix = postfix + infix.charAt(i);
}
else if(token == Precedence.rparen)
{
while(stack[top] != Precedence.lparen)
{
postfix = postfix + operators[pop().getIndex()];
}
pop();
}
else
{
while(top>=0 && isp[stack[top].getIndex()] >= icp[token.getIndex()])
{
postfix = postfix + operators[pop().getIndex()];
}
push(token);
} System.out.println("Postfix '"+postfix+"' Stack "+Arrays.deepToString(stack));
}
while(top>=0 && ( (token = pop()) != Precedence.eos) )
{
postfix = postfix + operators[token.getIndex()];
}
return postfix;
}
}
import java.util.ArrayList;
导入java.util.array;
公共级调车场
{
公共静态ArrayList符号=新ArrayList();
public static ArrayList letters=new ArrayList();
公共静态字符串路径=”;
公共静态void main(字符串参数[])
{
调车场sy=新调车场();
//扫描文件。
//扫描仪扫描=新扫描仪(System.in);
//String prompt=“请指定文件路径。\n使用以下格式:D:\\DiscreteMath\\inputFile.txt”;
//System.out.println(提示);
//path=scan.next();
//文件=新文件(路径);
字符串中缀=“(A | B)&C”;//字符串中缀=“(A | B)->!C”;
//试一试{
//
//扫描=新扫描仪(文件);
//中缀=scan.nextLine();
//
// }
//捕获(IOE异常)
// {
//System.err.println(“无文件”);
// }
//调用后缀函数
字符串后缀=sy.postfix(中缀);
System.out.println(“\n后缀表达式:“+postfix”);
字符串al=“A、B、C、D、E”;
//第38行
}
公共枚举优先级
{
//配置符号和操作数的优先级。
lparen(0)、rparen(1)、not(2)和(3)或(4)、mc(5)、bc(6)、eos(7)、操作数(8);
私有整数索引;
优先级(整数索引)
{
这个指数=指数;
}
public int getIndex()
{
收益指数;
}
}
私有静态final int[]isp={0,19,12,12,13,13,0};
私有静态final int[]icp={20,19,12,12,13,13,0};
私有静态最终字符串[]运算符={{{,“}”,“!”,“&”,“|”,“->,”“,”“,”“};
//初始化堆栈
私有优先级[]堆栈;
私人int top;
私有优先权
{
返回堆栈[top--];
}
专用无效推送(优先ele)
{
堆栈[++top]=ele;
}
//设置符号的优先级。
公共优先级getToken(字符串符号)
{
开关(符号)
{
大小写“(”:返回priority.lparen;
大小写“)”:返回priority.rparen;
大小写“!”:返回优先级。否;
大小写“&”:返回优先级。和;
大小写“|”:返回优先级。或;
大小写“->”:返回priority.mc;
案例“”:return priority.bc;
案例“”:返回priority.eos;
默认值:返回优先级。操作数;
}
}
//将中缀更改为后缀符号,然后返回字符串值。
公共字符串后缀(字符串中缀)
{
字符串后缀=”;
top=-1;
堆栈=新优先级[infix.length()];
优先标记;
对于(int i=0;i=0&&isp[stack[top].getIndex()]>=
Deque<Precedence> stack = new ArrayDeque<Precedence>();