`

表达式算法java实现

阅读更多
package bd;
import java.util.Scanner;
import java.util.Stack;

public class Calculator { 
      public static final String USAGE = "== usage ==\n" 
            + "input the expressions, and then the program " 
            + "will calculate them and show the result.\n" 
            + "input 'bye' to exit.\n"; 
      /**
       * @param args
       */ 
      public static void main(String[] args) { 
     
      String input = "(+ (- 12 2) (* 4 5))";
      toPolishNotation(input); 
      //toReversePolishNotation(input); 
     
           /* System.out.println(USAGE); 
            Scanner scanner = new Scanner(System.in); 
            String input = ""; 
            final String CLOSE_MARK = "bye"; 
            System.out.println("input an expression:"); 
            input = scanner.nextLine(); 
            while (input.length() != 0 
                  && !CLOSE_MARK.equals((input))) { 
                  System.out.print("Polish Notation (PN):"); 
                  try { 
                        toPolishNotation(input); 
                  } catch (NumberFormatException e) { 
                        System.out.println("\ninput error, not a number."); 
                  } catch (IllegalArgumentException e) { 
                        System.out.println("\ninput error:" + e.getMessage()); 
                  } catch (Exception e) { 
                        System.out.println("\ninput error, invalid expression."); 
                  } 
                  System.out.print("Reverse Polish Notation (RPN):"); 
                  try { 
                        toReversePolishNotation(input); 
                  } catch (NumberFormatException e) { 
                        System.out.println("\ninput error, not a number."); 
                  } catch (IllegalArgumentException e) { 
                        System.out.println("\ninput error:" + e.getMessage()); 
                  } catch (Exception e) { 
                        System.out.println("\ninput error, invalid expression."); 
                  } 
                  System.out.println("input a new expression:"); 
                  input = scanner.nextLine(); 
            }  */
            System.out.println("program exits"); 
      } 
      /**
       * parse the expression , and calculate it.
       * @param input
       * @throws IllegalArgumentException
       * @throws NumberFormatException
       */ 
      private static void toPolishNotation(String input) 
                  throws IllegalArgumentException, NumberFormatException { 
            int len = input.length(); 
            char c, tempChar; 
            Stack< Character> s1 = new Stack< Character>(); 
            Stack< Double> s2 = new Stack< Double>(); 
            Stack< Object> expression = new Stack< Object>(); 
            double number; 
            int lastIndex = -1; 
            for (int i=len-1; i>=0; --i) { 
                  c = input.charAt(i); 
                  if (Character.isDigit(c)) { 
                        lastIndex = readDoubleReverse(input, i); 
                        number = Double.parseDouble(input.substring(lastIndex, i+1)); 
                        s2.push(number); 
                        i = lastIndex; 
                        if ((int) number == number) 
                              expression.push((int) number); 
                        else 
                              expression.push(number); 
                  } else if (isOperator(c)) { 
                        while (!s1.isEmpty() 
                                    && s1.peek() != ')' 
                                    && priorityCompare(c, s1.peek()) < 0) { 
                              expression.push(s1.peek()); 
                              s2.push(calc(s2.pop(), s2.pop(), s1.pop())); 
                        } 
                        s1.push(c); 
                  } else if (c == ')') { 
                        s1.push(c); 
                  } else if (c == '(') { 
                        while ((tempChar=s1.pop()) != ')') { 
                              expression.push(tempChar); 
                              s2.push(calc(s2.pop(), s2.pop(), tempChar)); 
                              if (s1.isEmpty()) { 
                                    throw new IllegalArgumentException( 
                                          "bracket dosen't match, missing right bracket ')'."); 
                              } 
                        } 
                  } else if (c == ' ') { 
                        // ignore 
                  } else { 
                        throw new IllegalArgumentException( 
                                    "wrong character '" + c + "'"); 
                  } 
            } 
            while (!s1.isEmpty()) { 
                  tempChar = s1.pop(); 
                  expression.push(tempChar); 
                  s2.push(calc(s2.pop(), s2.pop(), tempChar)); 
            } 
            while (!expression.isEmpty()) { 
                  System.out.print(expression.pop() + " "); 
            } 
            double result = s2.pop(); 
            if (!s2.isEmpty()) 
                  throw new IllegalArgumentException("input is a wrong expression."); 
            System.out.println(); 
            if ((int) result == result) 
                  System.out.println("the result is " + (int) result); 
            else 
                  System.out.println("the result is " + result); 
      } 
      /**
       * parse the expression, and calculate it.
       * @param input
       * @throws IllegalArgumentException
       * @throws NumberFormatException
       */ 
      private static void toReversePolishNotation(String input) 
                  throws IllegalArgumentException, NumberFormatException { 
            int len = input.length(); 
            char c, tempChar; 
            Stack< Character> s1 = new Stack< Character>(); 
            Stack< Double> s2 = new Stack< Double>(); 
            double number; 
            int lastIndex = -1; 
            for (int i=0; i< len; ++i) { 
                  c = input.charAt(i); 
                  if (Character.isDigit(c) || c == '.') { 
                        lastIndex = readDouble(input, i); 
                        number = Double.parseDouble(input.substring(i, lastIndex)); 
                        s2.push(number); 
                        i = lastIndex - 1; 
                        if ((int) number == number) 
                              System.out.print((int) number + " "); 
                        else 
                              System.out.print(number + " "); 
                  } else if (isOperator(c)) { 
                        while (!s1.isEmpty() 
                                    && s1.peek() != '(' 
                                    && priorityCompare(c, s1.peek()) <= 0) { 
                              System.out.print(s1.peek() + " "); 
                              double num1 = s2.pop(); 
                              double num2 = s2.pop(); 
                              s2.push(calc(num2, num1, s1.pop())); 
                        } 
                        s1.push(c); 
                  } else if (c == '(') { 
                        s1.push(c); 
                  } else if (c == ')') { 
                        while ((tempChar=s1.pop()) != '(') { 
                              System.out.print(tempChar + " "); 
                              double num1 = s2.pop(); 
                              double num2 = s2.pop(); 
                              s2.push(calc(num2, num1, tempChar)); 
                              if (s1.isEmpty()) { 
                                    throw new IllegalArgumentException( 
                                          "bracket dosen't match, missing left bracket '('."); 
                              } 
                        } 
                  } else if (c == ' ') { 
                        // ignore 
                  } else { 
                        throw new IllegalArgumentException( 
                                    "wrong character '" + c + "'"); 
                  } 
            } 
            while (!s1.isEmpty()) { 
                  tempChar = s1.pop(); 
                  System.out.print(tempChar + " "); 
                  double num1 = s2.pop(); 
                  double num2 = s2.pop(); 
                  s2.push(calc(num2, num1, tempChar)); 
            } 
            double result = s2.pop(); 
            if (!s2.isEmpty()) 
                  throw new IllegalArgumentException("input is a wrong expression."); 
            System.out.println(); 
            if ((int) result == result) 
                  System.out.println("the result is " + (int) result); 
            else 
                  System.out.println("the result is " + result); 
      } 
      /**
       * calculate the two number with the operation.
       * @param num1
       * @param num2
       * @param op
       * @return
       * @throws IllegalArgumentException
       */ 
      private static double calc(double num1, double num2, char op) 
                  throws IllegalArgumentException { 
            switch (op) { 
            case '+': 
                  return num1 + num2; 
            case '-': 
                  return num1 - num2; 
            case '*': 
                  return num1 * num2; 
            case '/': 
                  if (num2 == 0) throw new IllegalArgumentException("divisor can't be 0."); 
                  return num1 / num2; 
            default: 
                  return 0; // will never catch up here 
            } 
      } 
      /**
       * compare the two operations' priority.
       * @param c
       * @param peek
       * @return
       */ 
      private static int priorityCompare(char op1, char op2) { 
            switch (op1) { 
            case '+': case '-': 
                  return (op2 == '*' || op2 == '/' ? -1 : 0); 
            case '*': case '/': 
                  return (op2 == '+' || op2 == '-' ? 1 : 0); 
            } 
            return 1; 
      } 
      /**
       * read the next number (reverse)
       * @param input
       * @param start
       * @return
       * @throws IllegalArgumentException
       */ 
      private static int readDoubleReverse(String input, int start) 
                  throws IllegalArgumentException { 
            int dotIndex = -1; 
            char c; 
            for (int i=start; i>=0; --i) { 
                  c = input.charAt(i); 
                  if (c == '.') { 
                        if (dotIndex != -1) 
                              throw new IllegalArgumentException( 
                                    "there have more than 1 dots in the number."); 
                        else 
                              dotIndex = i; 
                  } else if (!Character.isDigit(c)) { 
                        return i + 1; 
                  } else if (i == 0) { 
                        return 0; 
                  } 
            } 
            throw new IllegalArgumentException("not a number."); 
      } 
       
      /**
       * read the next number
       * @param input
       * @param start
       * @return
       * @throws IllegalArgumentException
       */ 
      private static int readDouble(String input, int start) 
      throws IllegalArgumentException { 
            int len = input.length(); 
            int dotIndex = -1; 
            char c; 
            for (int i=start; i< len; ++i) { 
                  c = input.charAt(i); 
                  if (c == '.') { 
                        if (dotIndex != -1) 
                              throw new IllegalArgumentException( 
                              "there have more than 1 dots in the number."); 
                        else if (i == len - 1) 
                              throw new IllegalArgumentException( 
                              "not a number, dot can't be the last part of a number."); 
                        else 
                              dotIndex = i; 
                  } else if (!Character.isDigit(c)) { 
                        if (dotIndex == -1 || i - dotIndex > 1) 
                              return i; 
                        else 
                              throw new IllegalArgumentException( 
                              "not a number, dot can't be the last part of a number."); 
                  } else if (i == len - 1) { 
                        return len; 
                  } 
            } 
             
            throw new IllegalArgumentException("not a number."); 
      } 
      /**
       * return true if the character is an operator.
       * @param c
       * @return
       */ 
      private static boolean isOperator(char c) { 
            return (c=='+' || c=='-' || c=='*' || c=='/'); 
      } 
分享到:
评论

相关推荐

    表达式求值 逆波兰表达式算法 java版

    表达式求值 逆波兰表达式算法,支持任何位数值运算,运算符支持+-*/(),其它运算符请自行扩展,代码比较松耦合可扩展性好

    使用Java语言实现后缀表达式的求值算法

    后缀表达式求值:使用Java语言实现后缀表达式的求值算法; 后缀表达式求值:使用Java语言实现后缀表达式的求值算法; 后缀表达式求值:使用Java语言实现后缀表达式的求值算法; 后缀表达式求值:使用Java语言实现...

    表达式计算器源代码 java实现

    根据提供的文件信息,我们可以从标题、描述以及部分代码中提炼出与Java实现的表达式计算器相关的知识点。 ### 表达式计算器源代码 Java实现 #### 1. 项目概述 这是一个基于Java Swing的图形界面计算器应用程序。...

    逆波兰表达式算法_表达式_

    - `ExpressionParserUtil.java` 文件可能包含了逆波兰表达式算法的具体实现,包括一个类`ExpressionParserUtil`,以及可能的解析、计算等方法。 - 类似的方法可能包括 `toPostfixExpression()`(将中缀表达式转换...

    Java身份证号码合法性校验算法,正则表达式。

    最完善的身份证号码合法性校验Java算法,适合Android平台,可以直接拿来在项目中使用,正则表达式。

    精通lambda表达式:Java多核编程

    通过学习《精通lambda表达式:Java多核编程》,开发者不仅能够掌握lambda表达式的语法和用法,还能了解到如何在现代Java应用中有效地利用多核处理器,实现程序性能的大幅提升。这本书对于想要提升Java并发编程能力的...

    实现一般表示式的合一算法

    本主题将详细阐述如何使用C++和Java这两种编程语言来实现一般表示式的合一算法。 合一,简单来说,就是寻找两个逻辑表达式之间的最一般解(Most General Unifier, MGU),即不改变表达式结构的前提下,找到一组替换...

    java实现的表达式计算器

    本文将深入探讨一个基于Java实现的表达式计算器项目,旨在帮助开发者理解如何在Java环境中设计和实现一个能解析并计算数学表达式的程序。 首先,我们来看“java实现的表达式计算器”这个标题,它揭示了我们的任务是...

    jep表达式计算java包,包括junit

    JEP通过其强大的解析器和求值引擎实现了这一功能,支持包括基本运算符(如+、-、*、/)、括号、函数调用以及变量等多种表达式结构。 **JEP的特点与功能**: 1. **表达式解析**:JEP可以解析包含变量、常量、运算符...

    逆波兰算法-java实现

    逆波兰算法,也称为后缀表达式算法,是一种在计算表达式时避免使用括号的算法。它基于栈数据结构,使得表达式求值过程更为直观。在这个Java实现的项目中,用户可以配置自定义表达式,系统会动态计算出结果。 首先,...

    java c++表达式求值(带括号和小数点)

    6. **Java实现** 在Java中,我们可以使用`Scanner`类读取输入表达式,`Stack&lt;Double&gt;`存储数字,`Stack&lt;Character&gt;`存储操作符。用循环遍历输入,根据字符类型执行相应的操作。 7. **C++实现** 在C++中,可以使用...

    Java算术表达式计算类库 ExpressionJ

    **Java算术表达式计算类库 ExpressionJ** ExpressionJ是一个强大的Java库,专门设计用于解析和计算数学算术表达式。这个库对于那些在应用程序中需要动态计算复杂数学表达式的开发者来说,是一个非常有用的工具。它...

    Java实现表达式计算器源码.zip

    总的来说,这个Java实现的表达式计算器项目综合运用了数据结构和算法,展示了Java在处理计算问题时的灵活性和强大性。通过学习和理解这个项目的源代码,开发者可以深入理解数据结构的运用、逆波兰表达式的计算以及...

    λ表达式在Java中的应用.pdf

    在实际应用中,λ表达式可以用来实现各种复杂的逻辑,例如,数据处理、算法实现、事件处理等。λ表达式也可以与Java 8中的其他新特性结合使用,例如,Stream API、Optional、方法引用等。 λ表达式是Java 8中的一种...

    表达式计算器(java)

    这个“表达式计算器(java)”项目显然旨在实现这样的功能,允许用户输入各种数学表达式并准确计算结果。下面我们将深入探讨相关的知识点。 首先,我们需要了解表达式计算的基本原理。在计算机科学中,表达式是根据...

    java栈实现计算器中缀表达式

    java数字栈和符号栈模拟计算器(中缀表达式) “计算中缀表达式”可以称得上是一个特别经典的关于栈的算法题,几乎在所有数据结构教材中都会涉及,而且很多公司面试或者笔试的时候都会把这道题作为一个考察点。可以说...

    java算术表达式求值

    Java算术表达式求值是程序设计中一个常见的任务,特别是在动态计算或用户输入解析的场景下。在Java中,处理这种需求通常涉及到解析和计算字符串形式的数学表达式。这个压缩包文件包含了多种资源,可以帮助我们理解并...

    构造正则表达式的简化DFA算法

    构造正则表达式的简化DFA算法论文 介绍了构造等价于给定正则表达式...个算法在计算机上已实现, 并且对输入的任意正则表达式, 都可以输出等价于正则 表达式的简化DFA. 该算法可以用于某些离散信息处理系统的设计与分析.

    山东大学 大数据实验二 倒排索引算法Java实现

    基于hadoop集群系统(也可以在伪分布式系统上运行)系统使用Java编写的倒排索引实现,具有使用停词表功能,使用正则表达式选择规范的单词。代码重构了setup(),map(),combiner(),partitation()和reducer()函数,...

Global site tag (gtag.js) - Google Analytics