【问题标题】:Postfix Calculator Java后缀计算器 Java
【发布时间】:2012-08-29 10:48:02
【问题描述】:

好的,所以我必须从文件中读取后缀表达式。后缀表达式必须有空格来分隔每个运算符或操作数。到目前为止,我只有在输入文件中的运算符或操作数之间没有空格时才有效。 (即如果文件有 12+,我得到的结果是 3。)为了做到这一点,我认为我需要对输入进行标记,但我不确定如何。这就是我到目前为止所拥有的。感谢您的任何回复。

import java.util.*;
import java.io.*;
public class PostfixCalc{
public static void main (String [] args) throws Exception {
File file = new File("in.txt");
Scanner sc = new Scanner(file);
String input = sc.next();
Stack<Integer> calc = new Stack<Integer>();
while(sc.hasNext()){
for(int i = 0; i < input.length(); i++){
    char c = input.charAt(i);
    int x = 0;
    int y = 0;
    int r = 0;
    if(Character.isDigit(c)){
       int t = Character.getNumericValue(c);
        calc.push(t);
    }
    else if(c == '+'){
        x = calc.pop();
        y = calc.pop();
        r = x+y;
        calc.push(r);
    }
     else if(c == '-'){
        x = calc.pop();
        y = calc.pop();
        r = x-y;
        calc.push(r);
    }
     else if(c == '*'){
        x = calc.pop();
        y = calc.pop();
        r = x*y;
        calc.push(r);
    }
     else if(c == '/'){
        x = calc.pop();
        y = calc.pop();
        r = x/y;
        calc.push(r);
    }
}
 }
 int a = calc.pop();
System.out.println(a);
 }
 } 

【问题讨论】:

  • 看看StringTokenizer。默认情况下,它会标记空白(空格、制表符、换行符等)。

标签: java calculator postfix-notation stack


【解决方案1】:

有几处你需要改变,你可以一步一步来。

  1. 声明您的Stack 包含Integers 而不是Characters。
  2. 在读取输入的代码中,依赖Strings 而不是Characters。
  3. 使用Integer.parseInt() 解析操作数。这会将Strings 转换为Integers。 (实际上,它将它们转换为ints,但在您的情况下,这种差异并不重要。)
  4. 使用Scanner.useDelimiter() 将扫描仪分隔符设置为\s+,这将匹配任何空白字符序列。

当然还有无数其他方法可以处理您的输入,但我试图让您了解如何更改现有代码以完成它需要做的事情。

【讨论】:

    【解决方案2】:

    为了进行标记,您可以使用带有单个空格的String.split() 作为分隔符

    String[] inputs = input.split(" ");
    

    这是我刚刚编写的完整解决方案,它使用基于单链表堆栈实现来制作后缀计算器;

    A - PostFixCalculator

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class PostFixCalculator {
    
        private static final String ADD = "+"; 
        private static final String SUB = "-";
        private static final String MUL = "*";
        private static final String DIV = "/";
    
        public void calculateFile(String fileName) throws IOException {
            BufferedReader br = null;
            StringBuilder sb = null;
            try {
                FileReader fileReader = new FileReader(fileName);
                br = new BufferedReader(fileReader);
    
                sb = new StringBuilder();
                String line = br.readLine();
    
                while (line != null) {
                    sb.append(line);
                    line = br.readLine();
                }
    
                String input = sb.toString();
                System.out.println(input + " = " + calculate(input));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                br.close();
            }
        }
    
        private int calculate(String input) {
            SinglyLinkedListStack<Integer> stack = new SinglyLinkedListStack<>();
    
            String[] inputs = input.split(" ");
    
            return handleCalculation(stack, inputs);
        }
    
        private static int handleCalculation(SinglyLinkedListStack<Integer> stack, String[] el) {
            int operand1, operand2;
    
            for(int i = 0; i < el.length; i++) {
                if( el[i].equals(ADD) || el[i].equals(SUB) || el[i].equals(MUL) || el[i].equals(DIV) ) {
                    operand2 = stack.pop();
                    operand1 = stack.pop();
                    switch(el[i]) {
                        case ADD: {
                            int local = operand1 + operand2;
                            stack.push(local);
                            break;
                        }
    
                        case SUB: {
                            int local = operand1 - operand2;
                            stack.push(local);
                            break;
                        }
    
                        case MUL: {
                            int local = operand1 * operand2;
                            stack.push(local);
                            break;
                        }
    
                        case DIV: {
                            int local = operand1 / operand2;
                            stack.push(local);
                            break;
                        }
                    }
                } else {
                    stack.push(Integer.parseInt(el[i]));
                }
            }
    
            return stack.pop();
        }
    
    }
    

    B - 单链表堆栈

    public class SinglyLinkedListStack<T> {
    
        private int size;
        private Node<T> head;
    
        public SinglyLinkedListStack() {
            head = null;
            size = 0;
        }
    
        public void push(T element) {
            if(head == null) {
                head = new Node(element);
            } else {
                Node<T> newNode = new Node(element);
                newNode.next = head;
                head = newNode;
            }
    
            size++;
        }
    
        public T pop() {
            if(head == null)
                return null;
            else {
                T topData = head.data;
    
                head = head.next;
                size--;
    
                return topData;
            }
        }
    
        public T top() {
            if(head != null)
                return head.data;
            else
                return null;
        }
    
        public int size() {
            return size;
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        private class Node<T> {
            private T data;
            private Node<T> next;
    
            public Node(T data) {
                this.data = data;
            }
    
        }
    
    }
    

    C - 演示

    import java.io.IOException;
    
    public class PostFixCalculatorDemo {
        public static void main(String[] args) throws IOException {
            PostFixCalculator calc = new PostFixCalculator();
            calc.calculateFile("postfix.txt");
        }
    }
    

    D - 示例输入文件:“postfix.txt”

    6 5 2 3 + 8 * + 3 + * 
    

    E - 演示输出

    6 5 2 3 + 8 * + 3 + *  = 288
    

    【讨论】:

      【解决方案3】:

      你不需要扫描仪

      只需使用BufferedReader读取文件,然后使用它的方法readLine来获取行

      然后使用

      String tokens[] = line.split("\\s+?") 
      

      您将获得“令牌”数组,可以在您的代码中进行处理。

      要识别号码,您可以使用以下正则表达式:

      Pattern isNumber = Pattern.compile("^\\d+?$")
      if (isNumber.matcher(token).matches()) {
          push(Integer.parseInt(token));
      }
      

      【讨论】:

      • 在这里使用扫描仪实际上更容易。 next() 默认情况下会检索下一个空格分隔的令牌。当然,以后可以使用模式。
      猜你喜欢
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2016-07-10
      • 2012-06-26
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多