任务:创建一个类RPNStack,它表示Node类型的对象堆栈。类RPNStack只包含Node类型顶部的一个私有字段。Node类型的对象表示在堆栈上推送的数据:每个对象在其字段val中包含对下一个节点的引用,在其字段中包含一个双值(在这里,单链列表顶部扮演的是头的角色)。类RPNStack提供了三种方法:
请注意,堆栈是一个单链接列表,其中添加和删除元素总是在开始时执行。主程序读取一个用反向波兰表示法(RPN)表示算术表达式的le,例如:2 7 5+*2 0-1 4//在读取每一行后,它被拆分(使用空格作为分隔符),对于每个标记:
在处理完行中的所有标记之后,我们会弹出堆栈的其余数字,这应该是整个表达式的值。然后,我们打印行和结果。我们还检查堆栈现在是否是空的;如果没有,我们会通知用户这个事实,我们清除堆栈,并对输入文件的其余行重复该过程。
我的实施:
我巧妙地修改程序,将其写入文件,只是为了练习。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) {
String fileName = "Numbers.txt";
String fileRes = "NumbersCalc.txt";
Path filein = Paths.get(fileName);
if (!Files.exists(filein) ||
!Files.isReadable(filein) ||
Files.isDirectory(filein)) {
System.out.println("Invalid input file !!!");
System.exit(1);
}
try (BufferedWriter bw =
Files.newBufferedWriter(Paths.get(fileRes));
BufferedReader br =
Files.newBufferedReader(filein)
) {
String line;
while ( (line = br.readLine()) != null) {
String[] lineParts = line.split("\\s+");
for (String string : lineParts) {
if(string.equals("+")){
RPNStack.push( RPNStack.pop() + RPNStack.pop() );
}else if(string.equals("-")){
RPNStack.push( RPNStack.pop() - RPNStack.pop() );
}else if(string.equals("*")){
RPNStack.push( RPNStack.pop() * RPNStack.pop() );
}else if(string.equals("/")){
RPNStack.push( RPNStack.pop() / RPNStack.pop() );
}else if(!string.equals("+") &&!string.equals("-")&&!string.equals("*")&&!string.equals("/")){
RPNStack.push(Double.parseDouble(string));
}
}
bw.write(RPNStack.pop()+System.lineSeparator()/*"\n"*/);
}
System.out.println("Results written to " + fileRes);
if(RPNStack.empty()) System.out.println("Stack is empty");
} catch(IOException e) {
System.out.println("Something wrong");
System.exit(1);
}
}
}
public class RPNStack {
private static Node top = null;
public static Node getTop() {
return top;
}
public static void push(double d){
if(top == null) top = new Node(d);
else top = new Node(d, top);
}
public static double pop(){
double buf = top.getVal();
top = top.getNext();
return buf;
}
public static boolean empty(){
if(top == null) return true;
else return false;
}
}
public class Node {
private double val;
private Node next;
public double getVal() {
return val;
}
public Node getNext() {
return next;
}
public Node(double val, Node next){
this.val=val;
this.next=next;
}
public Node(double val){
this(val,null);
}
}Numbers.txt:
2 7 5 + * 20 - 1 4 / /
2 7 5 + * 20 - 1 4 / /问题:
发布于 2016-02-10 18:11:57
if (!Files.exists(filein) ||
!Files.isReadable(filein) ||
Files.isDirectory(filein)) {
System.out.println("Invalid input file !!!");
System.exit(1);
}Invalid input file !!!,这三种消息中哪一种失败了?你能说出来吗?不用手动检查吗?思想的食粮。示例
boolean isFileReadable(File file) 请将ifs系列替换为switch语句。它会更容易读懂。
String result = "";
String first = RPNStack.pop();
String second = RPNStack.pop();
switch(string) {
case "+":
result = first + second;
break;
//similarly all others. The last else if will become default:
}
RPNStack.push(result);这样逻辑就清楚了。
\n不能在Windows上工作的原因是不同的操作系统有不同的行分隔符。快速的谷歌搜索可以告诉你这意味着什么。
假设方法应该是静态的,这将导致您有一个Stack。你不会想要那样的。static的意思是属于类,但是如果您想在程序中有两个堆栈呢?您应该有实例方法。
关于这个
System.out.println("Something wrong");怎么了?哪里?如果捕捉到异常,那么至少要将堆栈跟踪添加到打印的消息中。多么?谷歌搜索。
关于只捕获IOException,我说只捕获需要捕获的东西。如果您正在捕获异常,那么如果您可以在catch块中添加一些东西来恢复。如果不可能,那么至少记录一条不需要手动检查错误信息的错误消息。
现在还有什么可以做得更好呢?您可以使用Java的泛型使您的堆栈可重用。您应该创建一个Stack类,然后创建一个使用泛型堆栈类来完成其功能的RPNStack。在您的示例中,您所调用的Main实际上是逻辑上的RPNStack,而您已经命名的RPNStack类是一个堆栈。主类应该只给RPNStack字符串并得到结果。
https://codereview.stackexchange.com/questions/119521
复制相似问题