【问题标题】:How to use variables in stack?如何在堆栈中使用变量?
【发布时间】:2016-03-31 18:39:24
【问题描述】:

我正在尝试编写一个查找中缀的计算程序。此外,用户将为 x 变量输入数字,程序将解决它。我的程序有效,但它只在第一次解决它。接下来的时间它给出了与第一次相同的答案。

import java.util.Scanner;  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;

class Stack {
   char a[] = new char[100];
   int top = -1;

   void push(char c) {
       try {
           a[++top] = c;
       } catch (StringIndexOutOfBoundsException e) {
           System.out.println("Stack full , no room to push , size=100");
           System.exit(0);
       }
   }

   char pop() {
       return a[top--];
   }

   boolean isEmpty() {
       return (top == -1) ? true : false;
   }

   char peek() {
       return a[top];
   }

}

 public class intopost {

   static Stack operators = new Stack();

   public static void main(String argv[]) throws IOException {
       String infix;

       // create an input stream object
       BufferedReader keyboard = new BufferedReader(new InputStreamReader(
               System.in));

       // get input from user
       System.out.print("\nEnter the algebraic expression in infix: ");
       infix = keyboard.readLine();
       String postFx = toPostfix(infix);
       // output as postfix
       System.out.println("The expression in postfix is:" + postFx);

       if (postFx.contains("x")) {
           String line = "";
           do {
               System.out.println("Enter value of X : ");
               line = keyboard.readLine();
               if (!"q".equalsIgnoreCase(line)) {
                   postFx = postFx.replaceAll("x", line);
                   System.out.println("Answer to expression : "
                           + EvaluateString.evaluate(postFx));
               }
           } while (!line.equals("q"));
       } else {
           System.out.println("Answer to expression : "
                   + EvaluateString.evaluate(postFx));
       }

   }

   private static String toPostfix(String infix)
   // converts an infix expression to postfix
   {
       char symbol;
       String postfix = "";

       for (int i = 0; i < infix.length(); ++i)
       // while there is input to be read
       {
           symbol = infix.charAt(i);
           // if it's an operand, add it to the string
           if (symbol != ' ') {
               if (Character.isLetter(symbol) || Character.isDigit(symbol))
                   postfix = postfix + " " + symbol;
               else if (symbol == '(')
               // push (
               {
                   operators.push(symbol);
               } else if (symbol == ')')
               // push everything back to (
               {
                   while (operators.peek() != '(') {
                       postfix = postfix + " " + operators.pop();
                   }
                   operators.pop(); // remove '('
               } else
               // print operators occurring before it that have greater
               // precedence
               {
                   while (!operators.isEmpty() && !(operators.peek() == '(')
                           && prec(symbol) <= prec(operators.peek()))
                       postfix = postfix + " " + operators.pop();

                   operators.push(symbol);
               }
           }
       }
       while (!operators.isEmpty())
           postfix = postfix + " " + operators.pop();
       return postfix.trim();
   }

   static int prec(char x) {
       if (x == '+' || x == '-')
           return 1;
       if (x == '*' || x == '/' || x == '%')
           return 2;
       return 0;
   }
}

class EvaluateString {
   public static int evaluate(String expression) {
       char[] tokens = expression.toCharArray();

       // Stack for numbers: 'values'
       LinkedList<Integer> values = new LinkedList<Integer>();

       // Stack for Operators: 'ops'
       LinkedList<Character> ops = new LinkedList<Character>();

       for (int i = 0; i < tokens.length; i++) {
           // Current token is a whitespace, skip it
           if (tokens[i] == ' ')
               continue;

           // Current token is a number, push it to stack for numbers
           if (tokens[i] >= '0' && tokens[i] <= '9') {
               StringBuffer sbuf = new StringBuffer();
               // There may be more than one digits in number
               while (i < tokens.length && tokens[i] >= '0'
                       && tokens[i] <= '9')
                   sbuf.append(tokens[i++]);
               values.push(Integer.parseInt(sbuf.toString()));
           }

           // Current token is an opening brace, push it to 'ops'
           else if (tokens[i] == '(')
               ops.push(tokens[i]);

           // Closing brace encountered, solve entire brace
           else if (tokens[i] == ')') {
               while (ops.peek() != '(')
                   values.push(applyOp(ops.pop(), values.pop(), values.pop()));
               ops.pop();
           }

           // Current token is an operator.
           else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*'
                   || tokens[i] == '/') {
               // While top of 'ops' has same or greater precedence to current
               // token, which is an operator. Apply operator on top of 'ops'
               // to top two elements in values stack
               while (!ops.isEmpty() && hasPrecedence(tokens[i], ops.peek()))
                   values.push(applyOp(ops.pop(), values.pop(), values.pop()));

               // Push current token to 'ops'.
               ops.push(tokens[i]);
           }
       }

       // Entire expression has been parsed at this point, apply remaining
       // ops to remaining values
       while (!ops.isEmpty())
           values.push(applyOp(ops.pop(), values.pop(), values.pop()));

       // Top of 'values' contains result, return it
       return values.pop();
   }

   // Returns true if 'op2' has higher or same precedence as 'op1',
   // otherwise returns false.
   public static boolean hasPrecedence(char op1, char op2) {
       if (op2 == '(' || op2 == ')')
           return false;
       if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
           return false;
       else
           return true;
   }

   // A utility method to apply an operator 'op' on operands 'a'
   // and 'b'. Return the result.
   public static int applyOp(char op, int b, int a) {
       switch (op) {
       case '+':
           return a + b;
       case '-':
           return a - b;
       case '*':
           return a * b;
       case '/':
           if (b == 0)
               throw new UnsupportedOperationException("Cannot divide by zero");
           return a / b;
       }
       return 0;
   }

【问题讨论】:

  • 你试过调试吗?
  • 是的,但我没有运气
  • 您能提供示例用户输入吗?还有一些错误?
  • 这是我得到的输出示例。
  • 在中缀中输入代数表达式:5x+2 在后缀中的表达式为:5 x 2 + 输入 X 的值:2 表达式的答案:4 输入 X 的值:4 表达式的答案:4输入 X 的值:22222 表达式答案:4 输入 X 的值:

标签: java variables stack


【解决方案1】:

main 方法的 while 循环内部有错误。请参阅下面的 sn-p。

 postFx = postFx.replaceAll("x", line);
 System.out.println("Answer to expression : "
               + EvaluateString.evaluate(postFx));

这里postFx = postFx.replaceAll("x", line); 丢失了对包含变量x 的后缀形式的引用。 replaceAll 的后续调用没有任何效果。因此,对第一个输入值的表达式进行评估。
您可以通过将上面的代码替换为

来轻松修复它
 System.out.println("Answer to expression : "
               + EvaluateString.evaluate(postFx.replaceAll("x", line)));

【讨论】:

    猜你喜欢
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多