Java计算器实现(逆波兰式)

合集下载

逆波兰表达式、波兰表达式【数据结构与算法】

逆波兰表达式、波兰表达式【数据结构与算法】

逆波兰表达式、波兰表达式【数据结构与算法】逆波兰表达式、波兰表达式【数据结构与算法】1.前缀表达式⼜称波兰式,前缀表达式的运算符位于操作数之前。

⽐如:- × + 3 4 5 62.中缀表达式就是常见的运算表达式,如(3+4)×5-63.后缀表达式⼜称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后,⽐如:3 4 + 5 × 6 -⼈类最熟悉的⼀种表达式1+2,(1+2)3,3+42+4等都是中缀表⽰法。

对于⼈们来说,也是最直观的⼀种求值⽅式,先算括号⾥的,然后算乘除,最后算加减,但是,计算机处理中缀表达式却并不⽅便。

然后我们还需明确⼀些概念,下⾯通过我们最熟悉的中缀表达式画出⼀棵语法树来直观认识⼀下前后缀表达式的⽣成。

以A+B*(C-D)-E*F为例:中缀表达式得名于它是由相应的语法树的中序遍历的结果得到的。

上⾯的⼆叉树中序遍历的结果就是A+B*(C-D)-E*F。

前缀表达式是由相应的语法树的前序遍历的结果得到的。

上图的前缀表达式为- + A * B - C D * E F后缀表达式⼜叫做逆波兰式。

它是由相应的语法树的后序遍历的结果得到的。

上图的后缀表达式为:A B C D - * + E F * -下⾯我们关注两个点:1.如何根据⼀个逆波兰表达式求出运算结果?2.如果将⼀个中缀表达式转换成后缀表达式(逆波兰表达式)⼀.通过逆波兰表达式计算结果我们先看⼀个例⼦...后缀表达式3 4 + 5 × 6 -的计算1.从左⾄右扫描,将3和4压⼊堆栈;2.遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做⽐较),计算出3+4的值,得7,再将7⼊栈;3.将5⼊栈;4.接下来是×运算符,因此弹出5和7,计算出7×5=35,将35⼊栈;5.将6⼊栈;6.最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

从上⾯的过程我们如何编写代码实现呢?可以采⽤⼀个辅助的栈来实现计算,扫描表达式从左往右进⾏,如果扫描到数值,则压进辅助栈中,如果扫描到运算符,则从辅助栈中弹出两个数值参与运算,并将结果压进到栈中,当扫描表达式结束后,栈顶的数值就是表达式结果。

Java实现《编译原理》中间代码生成-逆波兰式生成与计算-程序解析

Java实现《编译原理》中间代码生成-逆波兰式生成与计算-程序解析

Java实现《编译原理》中间代码⽣成-逆波兰式⽣成与计算-程序解析Java 实现《编译原理》中间代码⽣成 -逆波兰式⽣成与计算 - 程序解析编译原理学习笔记(⼀)逆波兰式是什么?逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)⼀般的表达式⼜称中缀表达式,这种表达式的⼆元运算符放在两个运算量之间。

⽽逆波兰表达式⼜称后缀表达式,这种表达式把运算符放在运算量后⾯。

⽐如如 a+b 的逆波兰式表⽰为 ab+注意:逆波兰式是⼀个⽆括号表达式;逆波兰式的运算符出现的顺序就是原表达式的运算顺序。

(⼆)逆波兰式编译原理有什么关系?逆波兰式,三元式,四元式等是编译原理 - 中间代码⽣成阶段的常见的中间代码形式。

(三)本篇任务通过设计,使⽤ Java 语⾔编写⼀个逆波兰式⽣成程序,测试效果:(四)Java 源代码package com.java997.analyzer.rpn;import java.util.HashMap;import java.util.Map;import java.util.Scanner;import java.util.Stack;/*** <p>* 逆波兰式** @author XiaoPengwei* @since 2019-06-19*/public class RpnMain {/*** 检查算术表达术括号是否匹配, 语法是否正确** @param s 算术表达术* @return boolean*/public boolean isMatch(String s) {//括号符号栈Stack<Character> charStack = new Stack<>();//将表达式的字符串转换成数组char[] charArray = s.toCharArray();//遍历数组for (char aChar : charArray) {if (aChar == '(') {charStack.push(aChar);} else if (aChar == ')') {//如果是 ) , 且栈为空则返回 falseif (charStack.isEmpty()) {return false;} else {//如果是 ) , 且栈不为空则返回 false//peek() 是返回栈顶的值, 不做其他操作if (charStack.peek() == '(') {//把栈顶的值删除charStack.pop();}}}}//⾛到这⾥, 栈为空则表达式正确return charStack.empty();}/*** 判断是否为操作符 + - * /** @param charAt* @return boolean*/public boolean isOperator(char charAt) {return charAt == '+' || charAt == '-' || charAt == '*' || charAt == '/'; }/*** 根据正确的表达式, 获取逆波兰式** @param input* @return ng.String*/public StringBuilder getRpn(String input) {//结果StringBuilder sb = new StringBuilder();sb.append("The RPN is: ");//运算符栈Stack<Character> opStack = new Stack();//运算符优先级Map<Character, Integer> opMap = new HashMap(5);opMap.put('(', 0);opMap.put('+', 1);opMap.put('-', 1);opMap.put('*', 2);opMap.put('/', 2);//处理字符串for (int i = 0; i < input.length(); i++) {//如果是'('直接压栈if (input.charAt(i) == '(') {opStack.push('(');} else if (new RpnMain().isOperator(input.charAt(i))) {//如果是运算符char curOp = input.charAt(i);//如果运算符栈是空,就直接压栈if (opStack.isEmpty()) {opStack.push(curOp);} else if (opMap.get(curOp) > opMap.get(opStack.peek())) {//运算符栈不为空,且当当前运算符的优先级⽐站内第⼀个运算符的优先级⾼的时候,压栈 opStack.push(curOp);} else {//栈不为空,且运算符的优先级⼩于等于栈顶元素for (int j = 0; j <= opStack.size(); j++) {//弹出栈内第⼀个元素char ch = opStack.pop();sb.append(ch);if (opStack.isEmpty()) {opStack.push(curOp);break;} else if (opMap.get(curOp) > opMap.get(opStack.peek())) {opStack.push(curOp);break;}}}} else if (input.charAt(i) == ')') {//如果是')'就把站内'('上的元素都弹出栈for (int j = 0; j < opStack.size(); j++) {char c = opStack.pop();if (c == '(') {break;} else {sb.append(c);}}} else if ('A'<=input.charAt(i)&&input.charAt(i)<='Z'){//如果是字母就直接添加sb.append(input.charAt(i));}else if ('a'<=input.charAt(i)&&input.charAt(i)<='z'){//如果是字母就直接添加sb.append(input.charAt(i));}else if (Character.isDigit(input.charAt(i))){//如果是数字sb.append(input.charAt(i));}else {return new StringBuilder("But the expression contains unrecognizable characters");}}//把栈内剩余的运算符都弹出站for (int i = 0; i <= opStack.size(); i++) {sb.append(opStack.pop());}return sb;}public static void main(String[] args) {RpnMain rpnMain = new RpnMain();Scanner sc = new Scanner(System.in);while (true) {System.out.println("==========================\nPlease input an expression:");String input = sc.nextLine();if ("q".equals(input)) {sc.close();return;} else {if (rpnMain.isMatch(input)) {System.out.println("The expression's brackets are matched");// 获取逆波兰式System.out.println(rpnMain.getRpn(input));} else {System.out.println("Error: The expression's brackets are not matched! Enter 'q' to exit");}}}}}测试:。

逆波兰式(后缀表达式)的计算

逆波兰式(后缀表达式)的计算

逆波兰式(后缀表达式)的计算输⼊:后缀表达式(可带浮点数)输出:double型的计算结果代码:#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define ElemType double#define Stack_Init_Size 100#define Increase_Size 10#define MaxBuffer 10typedef struct sqStack{ElemType *top;ElemType *base;int initSize;}sqStack;typedef struct sqStack *LinkStack;//初始化void InitStack( sqStack *s ){s->base = (LinkStack)malloc(Stack_Init_Size * sizeof(ElemType));if(!s->base){printf("存储空间分配失败······\n");return;}s->top = s->base;s->initSize = Stack_Init_Size;}//进栈void Push(sqStack *s,ElemType e){if(s->top - s->base >= s->initSize - 1){s->base = (LinkStack)realloc(s->base,(s->initSize + Increase_Size) * sizeof(ElemType));//第⼀个s->base是增加后的存储空间块的地址,第⼆个是增加空间之前的存储空间块地址,后⾯是增加过的存储空间块的⼤⼩ if(!s->base){printf("增加存储空间失败······\n");return;}s->initSize = Increase_Size + Stack_Init_Size;}*(s->top) = e;(s->top)++;}//出栈void Pop(sqStack *s,ElemType *e){if(s->top == s->base){printf("栈已空,⽆法进⾏出栈操作······\n");return;}s->top--;*e = *s->top;}//求栈的长度int StackLen(sqStack s){return (s.top - s.base);}//逆波兰计算器:输⼊逆波兰式(后缀表达式)输出结果int main(){int i = 0,j,len;double m,n,t;char c;struct sqStack s;char str[MaxBuffer];InitStack(&s);printf("请输⼊您要计算的后缀表达式,按Enter键结束(两个不同的字符之间⽤空格隔开):\n");scanf("%c",&c);while(c != '\n'){while( (c >= '0'&&c <= '9') || c == '.'){str[i] = c;i++;// str[i] = '\0';if(i >= 10){printf("\n输⼊的数字过⼤导致出错\n"); return -1;}scanf("%c",&c);if( c == ' '){t = atof(str);// printf("\nt is %f\n",t);Push(&s,t);i = 0;for(j = 0;j < MaxBuffer;j++){str[j] = '\0';}break;}}switch( c ){case '+':Pop(&s,&m);Pop(&s,&n);Push(&s,n+m);break;case '-':Pop(&s,&m);Pop(&s,&n);Push(&s,n-m);break;case '*':Pop(&s,&m);Pop(&s,&n);Push(&s,n*m);break;case '/':Pop(&s,&m);Pop(&s,&n);if( m == 0){printf("\n除数为0,出错\n");return -1;}else{Push(&s,n/m);break;}}scanf("%c",&c);}Pop(&s,&t);printf("\n最终的计算结果为:%f \n",t);return 0;}。

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式解析sql where 语句-回复java逆波兰表达式解析SQL WHERE语句在编写程序时,经常需要对数据库进行操作,其中一个重要的操作就是查询数据。

SQL是一种经常使用的查询语言,而WHERE语句是SQL 中的关键字,用于过滤查询结果。

这篇文章将介绍如何使用Java来解析SQL语句中的WHERE条件,以及如何将WHERE条件转换为逆波兰表达式(Reverse Polish Notation,RPN)。

逆波兰表达式是一种用来表示及计算数学表达式的方法,其特点是将操作符放在操作数的后面。

例如,表达式"2 + 3"可以表示为"2 3 +",其中"+"是操作符,而"2"和"3"是操作数。

逆波兰表达式在计算机中使用广泛,其优点是可以通过栈结构进行计算,避免了使用括号来表示优先级。

首先,我们需要解析SQL语句中的WHERE条件。

假设有一个SQL 语句如下:SELECT * FROM table WHERE column1 = 5 AND column2 > 10 我们可以使用Java中的字符串分割功能来解析WHERE条件。

首先,我们需要使用空格将WHERE条件和SELECT语句分割开来。

然后,我们可以进一步使用逻辑运算符(AND、OR)来分割WHERE条件中的各个子条件。

在本例中,我们可以得到以下子条件:column1 = 5column2 > 10接下来,我们需要将每个子条件转换为逆波兰表达式。

对于每个子条件,我们可以将其分解为操作符、操作数1和操作数2。

在本例中,我们可以将子条件"column1 = 5"分解为:column15=其中,"column1"是操作数1,"5"是操作数2,"="是操作符。

用Java实现的计算器

用Java实现的计算器

用Java实现的计算器计算器是一个广泛应用的工具,用于进行数学运算。

如今,随着计算机技术的不断发展,计算器也逐渐被软件程序所替代。

本文将介绍如何使用Java语言实现一个简单的计算器程序。

一、程序概述计算器程序主要包括用户界面和计算逻辑两部分。

用户界面负责显示计算器的按钮和输入输出框,计算逻辑负责根据用户输入进行运算并返回结果。

二、用户界面设计在Java中,我们可以使用Swing或JavaFX等图形库来设计用户界面。

本文选用JavaFX来实现计算器的界面。

界面需要包括数字按钮、运算符按钮、输入输出框等组件。

在程序启动时,我们需要初始化界面并设置各个组件的位置、大小和样式。

为了方便布局,我们可以使用GridPane等布局管理器来管理组件。

三、计算逻辑实现1. 表达式解析计算器需要将用户输入的表达式解析为计算机可以识别的格式。

Java中可以使用正则表达式或者逆波兰表达式来解析表达式。

本文选用简单的正则表达式方法进行解析。

2. 运算逻辑解析表达式后,我们需要根据运算符的优先级进行运算。

Java中可以使用栈来实现运算符的优先级判断和运算。

我们可以定义一个操作数栈和一个运算符栈,按照规则将表达式中的数字和运算符依次入栈,并根据运算符的优先级进行运算并将结果入栈。

四、完整代码示例import javafx.application.Application;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.TextField;import yout.GridPane;import javafx.stage.Stage;public class Calculator extends Application {private TextField inputField; // 输入框private Button[] numberButtons; // 数字按钮private Button[] operatorButtons; // 运算符按钮@Overridepublic void start(Stage primaryStage) {primaryStage.setTitle("计算器");primaryStage.setResizable(false);// 初始化界面GridPane gridPane = new GridPane();gridPane.setHgap(10);gridPane.setVgap(10);gridPane.setPadding(new Insets(10));// 初始化输入框inputField = new TextField();inputField.setEditable(false);inputField.setPrefHeight(40);inputField.setMaxWidth(Double.MAX_VALUE);gridPane.add(inputField, 0, 0, 4, 1);// 初始化数字按钮numberButtons = new Button[10];for (int i = 0; i < 10; i++) {numberButtons[i] = createNumberButton(String.valueOf(i), i); }gridPane.add(numberButtons[7], 0, 1);gridPane.add(numberButtons[9], 2, 1);gridPane.add(numberButtons[4], 0, 2);gridPane.add(numberButtons[5], 1, 2);gridPane.add(numberButtons[6], 2, 2);gridPane.add(numberButtons[1], 0, 3);gridPane.add(numberButtons[2], 1, 3);gridPane.add(numberButtons[3], 2, 3);gridPane.add(numberButtons[0], 0, 4);gridPane.add(createDotButton(), 1, 4);gridPane.add(createEqualButton(), 2, 4);// 初始化运算符按钮operatorButtons = new Button[4];operatorButtons[0] = createOperatorButton("+"); operatorButtons[1] = createOperatorButton("-"); operatorButtons[2] = createOperatorButton("*"); operatorButtons[3] = createOperatorButton("/"); gridPane.add(operatorButtons[0], 3, 1);gridPane.add(operatorButtons[1], 3, 2);gridPane.add(operatorButtons[3], 3, 4);Scene scene = new Scene(gridPane);primaryStage.setScene(scene);primaryStage.show();}private Button createNumberButton(String text, int number) { Button button = new Button(text);button.setPrefSize(60, 40);button.setOnAction(e -> {String oldText = inputField.getText();inputField.setText(oldText + number);});return button;}private Button createDotButton() {Button button = new Button(".");button.setPrefSize(60, 40);button.setOnAction(e -> {String oldText = inputField.getText();inputField.setText(oldText + ".");});return button;}private Button createEqualButton() {Button button = new Button("=");button.setPrefSize(60, 40);button.setOnAction(e -> {String expression = inputField.getText();// 调用计算逻辑进行计算if (expression != null && !expression.isEmpty()) { double result = calculate(expression);inputField.setText(String.valueOf(result));}});return button;}private Button createOperatorButton(String text) {Button button = new Button(text);button.setPrefSize(60, 40);button.setOnAction(e -> {String oldText = inputField.getText();inputField.setText(oldText + text);});return button;}private double calculate(String expression) {// 进行计算逻辑的实现// ...}public static void main(String[] args) {launch(args);}}五、总结通过本文的介绍,我们可以了解到使用Java语言实现一个简单计算器的基本框架和思路。

(编译原理)逆波兰式算法的源代码

(编译原理)逆波兰式算法的源代码

一.实验目的1.深入理解算符优先分析法2.掌握FirstVt和LastVt集合的求法有算符优先关系表的求法3.掌握利用算符优先分析法完成中缀表达式到逆波兰式的转化二.实验内容及要求将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式,并计算用逆波兰式来表示的算术表达式的值。

程序输入/输出示例:输出的格式如下:(1)逆波兰式的生成及计算程序,编制人(2)输入一以#结束的中缀表达式(包括+—*/()数字#)(3)(4)逆波兰式备注:(1)在生成的逆波兰式中如果两个数相连则用&分隔,如28和68,中间用&分隔;(注意:1。

表达式中允许使用运算符(+-*/)、分割符(括号)、数字,结束符#;2。

如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;三.实验过程1、逆波兰式定义将运算对象写在前面,而把运算符号写在后面。

用这种表示法表示的表达式也称做后缀式。

逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。

采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。

2、产生逆波兰式的前提中缀算术表达式3、逆波兰式生成的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”.(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。

(4)如果不是数字,该字符则是运算符,此时需比较优先关系。

做法如下:将该字符与运算符栈顶的运算符的优先关系相比较.如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈.倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。

逆波兰式求表达式

逆波兰式求表达式
Stack<ExpressionNode> stackOperator = new Stack<ExpressionNode>(5);
ExpressionParser expParser = new ExpressionParser(expression);
{
lpNode = stackOperator.Pop();
if (lpNode.Type == ExpressionNodeType.LParentheses) break;
}
else
{
if (requireOperand)
{
//如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
{
unitaryNode = expNode;
}
else
{
}
listOperator.Add(expNode);
requireOperand = false;
}
else if (expNode.Type == ExpressionNodeType.LParentheses)
{
if (string.IsNullOrEmpty(expression)) return null;
List<ExpressionNode> listOperator = new List<ExpressionNode>(10);
return null;
}
}
else
{
if (stackOperator.Count == 0)
return null;

java 逆波兰表达式 解析sql where 语句

java 逆波兰表达式 解析sql where 语句

java 逆波兰表达式解析sql where 语句Java逆波兰表达式解析SQL WHERE语句引言:在进行SQL查询时,WHERE语句是常用的筛选条件。

然而,处理复杂的WHERE语句可能会变得棘手,尤其是对于包含多个嵌套条件的复杂查询。

解析这些查询条件并将其转换为可执行的代码是一个有趣而具有挑战性的问题。

为了解决这个问题,我们可以使用逆波兰表达式(RPN)作为解决方案。

本文将介绍如何使用Java来解析SQL WHERE语句并将其转换为RPN。

第一步:理解逆波兰表达式逆波兰表达式是一种无需括号即可表示计算顺序的表达式表示方法。

在逆波兰表达式中,操作数将直接跟在操作符后面,因此不需要使用括号来指定计算顺序。

例如,将`2 + 3 * 4`转换为逆波兰表达式的形式为`2 3 4 * +`。

逆波兰表达式的解析也非常简单。

我们可以使用一个栈来保存操作数,并在遇到操作符时执行相应的计算操作。

具体步骤如下:1. 遍历逆波兰表达式中的每个元素。

2. 如果遇到操作数,将其入栈。

3. 如果遇到操作符,从栈中弹出两个操作数,执行相应的计算操作,并将结果入栈。

4. 当遍历完所有元素后,栈中仅剩下一个元素,即为最终计算结果。

第二步:解析SQL WHERE语句现在,我们已经理解了逆波兰表达式的概念和解析方法,下面我们将重点关注如何将SQL WHERE语句转换为逆波兰表达式。

对于一个简单的WHERE语句,我们可以将其按照操作符的优先级转换为逆波兰表达式。

例如,将`age > 18 and gender = 'male'`转换为逆波兰表达式的形式为`age 18 > gender 'male' = and`。

然而,对于包含多个嵌套条件的复杂查询,我们需要使用更复杂的算法来解析。

一种常用的解析方法是使用递归下降法。

该方法的基本思路是通过递归地解析子表达式来构建整个表达式。

具体步骤如下:1. 将WHERE语句分割为多个子表达式。

java代码写的简易计算器(可以实现基本的加减乘除功能)

java代码写的简易计算器(可以实现基本的加减乘除功能)

java代码写的简易计算器(可以实现基本的加减乘除功能)计算器java写⼀个计算器,要求实现加减乘除功能,并且能够循环接收新的数据,通过⽤户交互实现。

import java.util.Scanner;/*** 计算器* 写4个⽅法:加减乘除* 利⽤循环加switch进⾏⽤户交互* 传递需要操作的两个数* 输出结果*/public class Demo04 {public static double a;public static double b;//运算符public static String operator;//=符public static String equal;//结果public static double sum=0;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("输⼊数字:");a = scanner.nextDouble();System.out.println("输⼊运算符:");operator = scanner.next();System.out.println("输⼊数字:");b = scanner.nextDouble();do {switch (operator){case "+":sum= add(a, b);System.out.println("输⼊=获取结果:");equal = scanner.next();coninue();break;case "-":sum=subtract(a,b);System.out.println("输⼊=获取结果:");equal = scanner.next();coninue();break;case "*":sum=multiply(a,b);System.out.println("输⼊=获取结果:");equal = scanner.next();coninue();break;case "/":if (b==0){System.out.println("被除数不能为0");operator = "q";break;}else {sum=divide(a,b);System.out.println("输⼊=获取结果:");equal = scanner.next();coninue();break;}default:System.out.println("运算符输⼊错误!");}}while (operator.equals("+")||operator.equals("-")||operator.equals("*")||operator.equals("/"));scanner.close();}//加public static double add(double a,double b){return a+b;}//减public static double subtract(double a,double b){return a-b;}//乘public static double multiply(double a,double b){return a*b;}//除public static double divide(double a,double b){return a/b;}//获得结果或再次输⼊public static void coninue(){Scanner scanner = new Scanner(System.in);if (equal.equals("=")){System.out.println(a+operator+b+"="+sum);System.out.println("输⼊运算符+,-,*,/继续或输⼊其他字符结束");operator=scanner.next();if (operator.equals("+")||operator.equals("-")||operator.equals("*")||operator.equals("/")){ System.out.println("输⼊数字:");b = scanner.nextDouble();a=sum;}else {System.out.println("输⼊错误!");}}else {System.out.println("输⼊错误!");}}}。

JAVA四则运算算法

JAVA四则运算算法

JAVA四则运算算法⼀、程序要求解析⼀般数学算式,实现简单的带括号的加减乘除运算。

⼆、基本思路前⾯两篇介绍了直接解析字符串和⽤数组容器辅助解析的两种⽅式,这次再介绍最常⽤的解析算法——解析后缀表达式(逆波兰表达式)。

三、逆波兰表达式及其得到算法1、逆波兰表达式也即后缀表达式,指的是不包含括号,运算符放在两个运算对象的后⾯,所有的计算按运算符出现的顺序,严格从左向右进⾏(不再考虑运算符的优先规则)。

(摘⾃百度),既然没了运算符的优先规则,那么计算机解析起来⾃然容易的多。

对于我们常见的表达式,称为中缀表达式,每个中缀表达式都有对应的后缀表达式。

如:中缀表达式:-2*(1+6/3)+4后缀表达式:-2 1 6 3 / + * 4 +(这⾥为了区分负号和减号,我在数字与数字、数字与符号之间都加了空格,⾄于怎么从中缀表达式得到后缀表达式,后⾯有介绍及参考程序)⽽在解析后缀表达式时,只需要遵守以下原则即可:从左往右遍历遇到数字直接放⼊容器遇到运算符,将最后两个数字取出,进⾏该运算,将结果再放⼊容器遍历结束后,容器中的数字即为运算结果按这个过程⾛下来,⾃然⽽然的想到⽤栈是最合适的。

现只需想办法由输⼊的中缀表达式转为后缀表达式即可完成解析。

2、由中缀表达式得到后缀表达式的算法由中缀表达式得到后缀表达式,只要遵守以下步骤即可:⾸先设置运算符的优先级(这样设置也是为了简化程序):”null” 栈顶若为空,假设优先级为0“(” 优先级设为1“+-” 优先级设为2“*/” 优先级设为3从左向右遍历中缀表达式遇到数字直接输出遇到符号遇到左括号,直接压栈遇到右括号,弹栈输出直到弹出左括号(左括号不输出)遇到运算符,⽐较栈顶符号,若该运算符优先级⼤于栈顶,直接压栈;若⼩于栈顶,弹栈输出直到⼤于栈顶,然后将改运算符压栈。

最后将符合栈弹栈并输出现根据这个原则,⼿动模拟⼀遍转换过程:还是以-2*(1+6/3)+4为例四、代码⼀环境:Eclipse Java EE IDE(Version: Oxygen.1a Release (4.7.1a))jdk1.8.0_131先写⼀个最基本的两位数四则运算⽅法,⽐较简单,没有写注释:private static double doubleCal(double a1, double a2, char operator) throws Exception {switch (operator) {case '+':return a1 + a2;case '-':return a1 - a2;case '*':return a1 * a2;case '/':return a1 / a2;default:break;}throw new Exception("illegal operator!");} 写⼀个获得优先级的⽅法:private static int getPriority(String s) throws Exception {if(s==null) return 0;switch(s) {case "(":return 1;case "+":;case "-":return 2;case "*":;case "/":return 3;default:break;}throw new Exception("illegal operator!");}将中缀表达式转变为后缀表达式:private static String toSufExpr(String expr) throws Exception {System.out.println("将"+expr+"解析为后缀表达式...");/*返回结果字符串*/StringBuffer sufExpr = new StringBuffer();/*盛放运算符的栈*/Stack<String> operator = new Stack<String>();operator.push(null);//在栈顶压⼈⼀个null,配合它的优先级,⽬的是减少下⾯程序的判断/* 将expr打散分散成运算数和运算符 */Pattern p = pile("(?<!\\d)-?\\d+(\\.\\d+)?|[+\\-*/()]");//这个正则为匹配表达式中的数字或运算符Matcher m = p.matcher(expr);while (m.find()) {String temp = m.group();if (temp.matches("[+\\-*/()]")) { //是运算符if (temp.equals("(")) { //遇到左括号,直接压栈operator.push(temp);System.out.println("'('压栈");} else if (temp.equals(")")) { //遇到右括号,弹栈输出直到弹出左括号(左括号不输出)String topItem = null;while (!(topItem = operator.pop()).equals("(")) {System.out.println(topItem+"弹栈");sufExpr.append(topItem+" ");System.out.println("输出:"+sufExpr);}} else {//遇到运算符,⽐较栈顶符号,若该运算符优先级⼤于栈顶,直接压栈;若⼩于栈顶,弹栈输出直到⼤于栈顶,然后将改运算符压栈。

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式解析sql where 语句-回复Java逆波兰表达式解析SQL WHERE语句-提高条件判断效率在数据库中,SQL WHERE子句用于筛选满足条件的数据。

在复杂的查询中,处理WHERE语句可能会涉及到多个逻辑运算符和表达式。

为了提高条件判断的效率,可以使用逆波兰表达式来解析WHERE语句。

本文将逐步回答有关Java逆波兰表达式解析SQL WHERE语句的问题。

1. 什么是逆波兰表达式?逆波兰表达式,又称为后缀表达式,是一种将运算符放在操作数之后的数学表达式。

它没有括号,因此可以通过栈的方式非常方便地计算出结果。

例如,表达式"3 + 4 * 2"可以用逆波兰表达式表示为"3 4 2 * +"。

2. 逆波兰表达式与SQL WHERE语句有什么关系?逆波兰表达式在处理WHERE语句中的条件判断时非常有用。

SQL WHERE语句中的逻辑运算符和表达式可以通过逆波兰表达式转换,使其更容易理解和计算。

逆波兰表达式的解析可以提高条件判断的效率,并减少计算过程中的错误。

3. Java中如何解析逆波兰表达式?可以使用栈来解析逆波兰表达式。

首先,将逆波兰表达式拆分成操作数和运算符,并按顺序处理。

遇到操作数时,将其推入栈中;遇到运算符时,从栈中弹出相应数量的操作数进行计算,并将结果推入栈中。

最后,栈中的唯一元素即为表达式的计算结果。

4. 如何将SQL WHERE语句转换为逆波兰表达式?将SQL WHERE语句转换为逆波兰表达式需要按照一定的规则进行。

首先,将WHERE语句拆分成多个表达式片段,然后按照优先级和括号的方式重新排列。

例如,将"age > 18 AND (gender = 'M' OR gender = 'F')"转换为"age 18 > gender 'M' gender 'F' OR AND"。

编译原理课程设计-简单计算器实现

编译原理课程设计-简单计算器实现

课程设计报告课程:编译原理学号:姓名:班级:11级嵌入式应用技术班教师:时间:2014年6月计算机科学与技术系输入一个简单运算表达式A=当前输入符号A是运算符吗?根据运算符的特点从栈顶部取出若干个运算对象进行该运算,将运果入栈将该字符入栈A=‘\0’程序结束是否是否图二表达式结果计算流程图结果与分析(可以加页):图三实现计算器加法功能图四实现计算器减法功能图五实现计算器乘法功能图六实现计算器除法功能图七实验计算器混合运算功能源代码:#include〈stdio。

h> #include<stdlib.h〉#define MaxSize 99void translate(char str[],char exp[]){struct{char data[MaxSize];int top;}op;char ch;int i = 0,t = 0;op.top = -1;ch = str[i];i++;while(ch != ’\0’){switch(ch){case ’(':op.top++;op。

data[op.top]=ch;break;case ’)':while(op.data[op.top]!= ’('){exp[t]=op.data[op.top];op。

top--;t++;}op.top-—;break;case ’+’:case '—’:while(op.top != -1&&op。

data[op。

top] != '(’){exp[t]= op.data[op.top];op。

top——;t++;}op。

top++;op。

data[op。

top] = ch;break;case '*’:case ’/’:while(op。

data[op。

top] == ’/'||op.data[op。

top] == '*'){exp[t] = op.data[op.top];op。

Java计算器实现(逆波兰式)

Java计算器实现(逆波兰式)

package hfw.util;import java.util.ArrayDeque;import java.util.Deque;/****逆波兰式*总结,java版的Eval:逆波兰和动态编译,推荐用动态编译,因为逆波兰式不认识"- 4",只认识"-4"*@author zyh*/public class RNP {/*** 运算数*/private static Deque<String> operationNum = new ArrayDeque<String>();/*** 运算符*/private static Deque<String> operator = new ArrayDeque<String>();/*** 将表达式转换为逆波兰式* @param expression* @return*/private static void str2Rnp(String expression){operationNum.clear();operator.clear();int index = 0;for(int i=0;i<expression.length();i++){char c = expression.charAt(i);if(isOperator(c) || c=='(' || c==')'){//操作数直接入栈String operationNum = expression.substring(index,i);//区分负号和减号,如果'-'前面的一个是+-*/( 认为是负号,'-'前面的是数或)认为是减号if(c=='-'){int in = i;while((expression.charAt(in-1)) ==' '){in--;if(in==0){break;}}if(in==0){continue;}String previous = expression.substring(in-1,i);if(isOperator(previous.charAt(0)) || previous.charAt(0)=='('){continue;}}if(operationNum.trim().length()>0){RNP.operationNum.push(operationNum.trim());}index = i+1;String operator = c+"";//如果操作符是'(',直接入栈if('('==c){RNP.operator.push(operator);//如果操作符是')',将'('操作符之后的全部出栈,入栈操作数,'(' ')'舍弃}else if(')'==c){while(true){String o = RNP.operator.pollFirst();if(o==null || "(".equals(o)){break;}RNP.operationNum.push(o);}//如果操作符是+-*/}else{String o = RNP.operator.peekFirst();if(o== null){//如果操作符栈为空,操作符直接入栈RNP.operator.push(operator);}else {char operator2 = o.charAt(0);//比较操作符,和操作符栈首的大小,如果操作符大,直接入栈if(operator2=='(' || operator2==')' || orderOperator(c,operator2)){RNP.operator.push(operator);//如果操作符栈首大,将操作符栈小于操作符的全部出栈,入栈操作数,最后改操作符入栈}else{while(true){if(o==null || o.charAt(0) =='('|| o.charAt(0) ==')'){break;}if(orderOperator(c, o.charAt(0))){break;}o = RNP.operator.pollFirst();RNP.operationNum.push(o);o = RNP.operator.peekFirst();}RNP.operator.push(operator);}}}}}String operationNum = expression.substring(index);if(operationNum.trim().length()>0){RNP.operationNum.push(operationNum.trim());}while(RNP.operator.size()>0){RNP.operationNum.push(RNP.operator.pollFirst());}// RNP.operationNum.addAll(RNP.operator);}//判断一个字符是否为运算符private static boolean isOperator(char c) {return c=='+' || c=='-' || c=='*' || c=='/';}//判断运算符顺序,true表示运算符operator1>operator2,false表示相等或小于private static boolean orderOperator(char operator1, char operator2){if((operator1=='*' || operator1=='/') && (operator2=='+' || operator2=='-')){ return true;}return false;}/*** 计算逆波兰式的值* @return*/private static double countRnp(){while(RNP.operationNum.size()>0){String s = RNP.operationNum.pollLast();//如果是操作符,取出栈顶的两个操作数,直接运算char operator = s.charAt(0);if(s.length()==1 && isOperator(operator)){String a = RNP.operator.pollFirst();String b = RNP.operator.pollFirst();if('+'==operator){double result = Double.parseDouble(b)+Double.parseDouble(a);RNP.operator.push(result+"");}else if('-'==operator){double result = Double.parseDouble(b)-Double.parseDouble(a);RNP.operator.push(result+"");}if('*'==operator){double result = Double.parseDouble(b)*Double.parseDouble(a);RNP.operator.push(result+"");}if('/'==operator){double result = Double.parseDouble(b)/Double.parseDouble(a);RNP.operator.push(result+"");}//如果是操作数,入栈}else{RNP.operator.push(s);}}double result = Double.parseDouble(RNP.operator.pollLast());return result;}/*** 计算逆波兰式的值(整数)* @return*/private static int intRnp(){while(RNP.operationNum.size()>0){String s = RNP.operationNum.pollLast();//如果是操作符,取出栈顶的两个操作数,直接运算char operator = s.charAt(0);if(s.length()==1 && isOperator(operator)){String a = RNP.operator.pollFirst();String b = RNP.operator.pollFirst();if('+'==operator){int result = Integer.parseInt(b)+Integer.parseInt(a);RNP.operator.push(result+"");}else if('-'==operator){int result = Integer.parseInt(b)-Integer.parseInt(a);RNP.operator.push(result+"");}if('*'==operator){int result = Integer.parseInt(b)*Integer.parseInt(a);RNP.operator.push(result+"");}if('/'==operator){int result = Integer.parseInt(b)/Integer.parseInt(a);RNP.operator.push(result+"");}//如果是操作数,入栈}else{RNP.operator.push(s);}}int result = Integer.parseInt(RNP.operator.pollLast());return result;}/*** 计算表达式的值* @param expression* @return*/public static double calculate(String expression){try{str2Rnp(expression);return countRnp();}catch(Exception e){e.printStackTrace();System.out.println("请检查表达式");return 0.0;}}/*** 计算表达式的值(整数)* @param expression* @return*/public static int intCalculate(String expression){try{str2Rnp(expression);return intRnp();}catch(Exception e){e.printStackTrace();System.out.println("请检查表达式");return 0;}}public static void main(String[] args) {String s= "53.12* 6/ ( -12-7.2)* -6 *( -4)*12*6/7.2-6";System.out.println(RNP.calculate(s));s = "((( -1+ 2 ) * -2) * -4)-9*( -1 + 2)";System.out.println(RNP.intCalculate(s));}}。

逆波兰序实现计算器

逆波兰序实现计算器

双数组逆波兰表达式法:计算器见源程(c语言):#include "stdio.h"#define m0 100void main(){char str[m0];char exp[m0];char stack[m0];float stack1[m0],d;char ch,c;int i,j,t,top=0;i=0;clrscr();do{i++;scanf("%c",&str[i]);}while (str[i]!=’#’&&i!=m0); t=1;i=1;ch=str[i];i++;while(ch!=’#’){if(ch>=’0’&&ch<=’9’){exp[t]=ch;t++;}elseif(ch==’(’)top++;stack[top]=ch;}elseif(ch==’)’){while(stack[top]!=’(’){exp[t]=stack[top];top--;t++;}top--;}elseif (ch==’+’||ch==’-’){while(top!=0&&stack[top]!=’(’){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch==’*’||ch==’/’){while(stack[top]==’*’||stack[top]==’/’) {exp[t]=stack[top];top--;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}ex p[t]=’#’;for(j=1;j<=t;j++)printf("%c",exp[j]); printf("\n");exp[t+1]=’\0’;t=1;top=0;c=exp[t];t++;while(c!=’#’){if(c>=’0’&&c<=’9’){d=c-’0’;top++;stack1[top]=d;}else{switch (c){case ’+’:stack1[top-1]=stack1[top-1]+stack1[top];break; case ’-’:stack1[top-1]=stack1[top-1]-stack1[top];break; case ’*’:stack1[top-1]=stack1[top-1]*stack1[top];break; case ’/’:if(stack1[top]!=0)stack1[top-1]=stack1[top-1]/stack1[top];elseprintf("ERROR!!! Zero can not be divided.\n");getch();exit(0);}top--;}c=exp[t];t++;}printf("The mark is %g",stack1[top]);getch();}例:输入:1+2×(4+6)#;程序将数据转换为中序,再输出:1246+*+#;再计算。

Java版逆波兰表达式(后缀表达式)

Java版逆波兰表达式(后缀表达式)

Java版逆波兰表达式(后缀表达式)逆波兰表达式⼜称后缀表达式,将运算符写在操作数之后,便于计算机计算将中缀表达式转换成后缀表达式的8个步骤:1. 初始化两个栈,运算符栈s1和存储中间结果的栈s22. 从左⾄右扫描中缀表达式3. 遇到操作数时,将其压⼊s24. 遇到运算符时,将其与s1栈顶运算符的优先级进⾏⽐较:1. 如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符⼊栈2. 否则,若优先级⽐栈顶运算符的⾼,也将运算符压⼊s13. 否则,将s1栈顶的运算符弹出并压⼊到s2中,再次转到(4.1)与s1中的栈顶运算符相⽐较5. 遇到括号时:1. 如果是左括号"(",则直接压⼊s12. 如果是右括号")",则依次弹出s1栈顶的运算符,并压⼊s2,直到遇到左括号为⽌,此时将这⼀对括号丢弃6. 重复步骤2⾄5,知道表达式最右边7. 将s1中剩余的运算符以此弹出并压⼊s28. 依次弹出s2中的元素并输⼊,结果的逆序即为中缀表达式对应的后缀表达式。

1+(2+3)*4 -5 的转换步骤代码实现/*** 转换成后缀表达式List** @param ls 中缀表达式List*/public static List<String> parseSuffixExpression(List<String> ls) {Stack<String> s1 = new Stack<>();//运算符栈Queue<String> s2 = new ArrayDeque<>();//临时队列for (String item : ls) {if (item.matches("\\d+")) {//3.如果是数字,直接⼊队s2s2.offer(item);} else if (isOper(item)) {//4.如果是运算符while (true) {if (s1.isEmpty() || "(".equals(s1.peek())) {//4.1如果运算符栈s1是空的,或栈顶是左括号,则直接⼊栈s1.push(item);break;} else if (priority(item) > priority(s1.peek())) {//4.2否则,若运算符优先级⽐栈顶的⾼,也⼊栈s1.push(item);break;} else {//4.3 否则,直接把栈顶的元素⼊队,继续转到4.1与新的栈顶元素⽐较s2.offer(s1.pop());}}} else if ("(".equals(item)) {//5.1如果遇到左括号( ,直接压⼊s1s1.push(item);} else if (")".equals(item)) {//5.2如果是右括号while (true) {String top = s1.pop();//弹出栈顶元素if ("(".equals(top)) {//碰到左括号,丢弃这对括号break;} else {//否则⼊队s2.offer(top);}}} else {throw new RuntimeException("⽆法识别的字符" + item + ",表达式不正确");}}while (!s1.isEmpty()) {//7.将s1剩余的表达式依次弹出并⼊队s2.offer(s1.pop());}List<String> res = new ArrayList<>();while (!s2.isEmpty()) {res.add(s2.poll());}return res;}后缀表达式的计算规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进⾏运算,运算结果进栈,⼀直到最终获得结果。

逆波兰表达式计算 java

逆波兰表达式计算 java

逆波兰表达式计算java下面是一个用Java实现逆波兰表达式计算的简单例子:```javaimport java.util.Stack;public class RPNCalculator {public static void main(String[] args) {String expression = "3 4 + 2 *";System.out.println(calculate(expression)); // 输出: 14 }public static int calculate(String expression) {Stack<Integer> stack = new Stack<>();String[] tokens = expression.split(" ");for (String token : tokens) {if (isOperator(token)) {int operand2 = stack.pop();int operand1 = stack.pop();int result = calculateOperation(token, operand1, operand2);stack.push(result);} else {stack.push(Integer.parseInt(token));}}return stack.pop();}private static boolean isOperator(String token) {return token.equals("+") || token.equals("-") || token.equals("*");}private static int calculateOperation(String operation, int operand1, int operand2) {switch (operation) {case "+": return operand1 + operand2;case "-": return operand1 - operand2;case "*": return operand1 * operand2;default: throw new IllegalArgumentException("Invalid operation: " + operation);}}}```这个程序首先将输入的逆波兰表达式分割成一个个的标记(token),然后遍历这些标记。

后缀表达式(逆波兰表达式)计算器

后缀表达式(逆波兰表达式)计算器

后缀表达式(逆波兰表达式)计算器package datastructure.stack;import java.util.*;/*** <h3>netty_lecture</h3>* <p>逆波兰计算器</p>* 1+((2+3)*4)-5 ==> 1 2 3 + 4 * + 5 1* @author : myron* @date : 2020-03-18 23:48**/public class PolandNotation {private static final int MINAS = 0;private static final int PLUS = 0;private static final int MULTI = 1;private static final int DIV = 1;public static void main(String[] args){String expression = "1,+,(,(,200,+,3,),*,9,),-,5";List<String> list = middleExpressionToList(expression);List<String> suffixExp = middleExpToSuffixExp(list);System.out.println("中缀表达式:"+ list);System.out.println("后缀表达式:" + suffixExp);int result = calculate(suffixExp);System.out.println("结果为:" + result);}/*** 中缀表达式转List* @param expression* @return*/public static List<String> middleExpressionToList(String expression){String[] split = expression.split(",");List<String> list = Arrays.asList(split);return list;}/*** 中缀表达式转后缀表达式list* @param middleExpList* @return*/public static List<String> middleExpToSuffixExp(List<String> middleExpList){Stack<String> s1 = new Stack<>();List<String> s2 = new ArrayList<>();for (String oper:middleExpList){int priority = getPriority(oper);if(oper.matches("\\d+")){s2.add(oper);}else if("(".equals(oper)) {s1.push(oper);} else if(")".equals(oper)){while(!"(".equals(s1.peek())){s2.add(s1.pop());}s1.pop();}else{while(s1.size() != 0 && priority <= getPriority(s1.peek())){s2.add(s1.pop());}s1.push(oper);}}while(s1.size() != 0){s2.add(s1.pop());}return s2;}/*** 计算⽅法* @param list :后缀表达式* @return*/public static int calculate(List<String>list){//创建栈Stack<String> stack = new Stack<>();//遍历表达式listfor(String str: list){/**正则匹配,是数字,⼊栈*/if(str.matches("\\d+")){stack.push(str);/**运算符,则弹出两位数,进⾏运算*/}else{int num1 = Integer.parseInt(stack.pop());int num2 = Integer.parseInt(stack.pop());int result = 0;if(str.equals("+")){result = num1 + num2;}else if(str.equals("-")){result = num2 - num1;}else if(str.equals("*")){result = num1 * num2;}else if(str.equals("/")){result = num2/num1;}else{throw new RuntimeException("不⽀持该符号!"); }//预算结果⼊栈stack.push(result + "");}}//返回运算结果return Integer.parseInt(stack.pop());}/*** 获取符号的优先级*/public static int getPriority(String oper){if (oper.equals("+")) {return PLUS;}else if(oper.equals("-")){return MINAS;}else if(oper.equals("*")){return MULTI;}else if(oper.equals("/")){return DIV;}return -1;}}。

java计算加减混合运算表达式

java计算加减混合运算表达式

java计算加减混合运算表达式
Java计算加减混合运算表达式是一种常见的数学运算,可以用来计算多个数的加减混合运算结果。

在Java中,可以使用各种算法和数据结构来实现这种运算表达式的计算。

其中,常见的算法包括逆波兰表达式算法、栈算法和递归算法等。

在使用逆波兰表达式算法计算加减混合运算表达式时,需要将表达式转换成逆波兰表达式,并使用栈来存储数字和运算符。

逆波兰表达式是一种将运算符放在操作数后面的表达式形式,可以避免使用括号和优先级判断,从而简化计算过程。

使用栈算法时,可以将数字和运算符分别存储在两个栈中,利用栈后进先出的特点,按照运算符的优先级进行计算。

使用递归算法时,可以将加减运算分解成多个小的加减运算,再递归计算每个小的加减运算结果。

无论使用哪种算法,都需要注意输入表达式的有效性和正确性,避免出现计算错误和异常情况。

- 1 -。

逆波兰式分析

逆波兰式分析

2010-07-22逆波兰表达式文章分类:Java编程转贴(忘了弄URL了,来自CSDN,上面的文字部分是转的,下面的实现是我的)逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。

例如(a+b)*(c+d)转换为ab+cd+*d+。

它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。

其运算方式如下:如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

将一个普通的中序表达式转换为逆波兰表达式的一般算法是:(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号"#"。

(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。

(4)如果不是数字,该字符则是运算符,此时需比较优先关系。

做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。

如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。

倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。

(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。

其中运算符优先级如下:*/:4+-:3(:2):1中缀表达式到后缀表达式的转换要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。

优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。

如果所有操作符优先级一样,那么求值顺序就取决于它们的结合性。

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式 解析sql where 语句 -回复

java 逆波兰表达式解析sql where 语句-回复如何使用逆波兰表达式解析SQL WHERE语句?逆波兰表达式是一种基于堆栈的算术表达式的表示方法。

它非常适合用于解析和计算复杂的表达式,例如SQL WHERE语句中的条件。

在本文中,我们将一步一步地解释如何使用逆波兰表达式来解析SQL WHERE语句。

第一步:了解逆波兰表达式的基本原理逆波兰表达式使用后缀表示法,其中操作数位于运算符之后。

例如,将中缀表达式"2 + 3" 转换为逆波兰表达式时变为"2 3 +"。

为了计算逆波兰表达式,我们需要使用一个堆栈来存储操作数和结果。

第二步:将SQL WHERE语句转换为逆波兰表达式在解析SQL WHERE语句之前,我们需要明确一些规则。

假设我们的SQL WHERE语句只包含AND和OR逻辑操作符,以及字段、比较运算符和常量。

我们的目标是将SQL WHERE子句转换为逆波兰表达式。

为了实现这一目标,我们可以使用递归下降法。

我们首先将WHERE 子句中的第一个条件解析为逆波兰表达式,并将其添加到结果列表中。

然后,我们检查子句的下一个部分是AND还是OR操作符。

如果是AND 操作符,我们将其添加到结果列表中,并继续解析下一个条件。

如果是OR操作符,我们将其添加到结果列表中,并继续解析下一个条件。

我们重复这个过程,直到解析完整个SQL WHERE语句。

第三步:计算逆波兰表达式的值一旦我们将SQL WHERE语句成功转换为逆波兰表达式,我们就可以使用堆栈来计算其值。

我们遍历逆波兰表达式,并按照以下规则进行操作:- 如果是操作数(字段、比较运算符或常量),我们将其压入堆栈。

- 如果是操作符(AND或OR),我们从堆栈中弹出两个操作数,并根据操作符的类型执行相应的逻辑操作。

然后,我们将结果压入堆栈。

- 重复上述步骤,直到遍历完整个逆波兰表达式。

- 最后,我们从堆栈中弹出最终的结果,它就是逆波兰表达式的值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

package hfw.util;import java.util.ArrayDeque;import java.util.Deque;/****逆波兰式*总结,java版的Eval:逆波兰和动态编译,推荐用动态编译,因为逆波兰式不认识"- 4",只认识"-4"*@author zyh*/public class RNP {/*** 运算数*/private static Deque<String> operationNum = new ArrayDeque<String>();/*** 运算符*/private static Deque<String> operator = new ArrayDeque<String>();/*** 将表达式转换为逆波兰式* @param expression* @return*/private static void str2Rnp(String expression){operationNum.clear();operator.clear();int index = 0;for(int i=0;i<expression.length();i++){char c = expression.charAt(i);if(isOperator(c) || c=='(' || c==')'){//操作数直接入栈String operationNum = expression.substring(index,i);//区分负号和减号,如果'-'前面的一个是+-*/( 认为是负号,'-'前面的是数或)认为是减号if(c=='-'){int in = i;while((expression.charAt(in-1)) ==' '){in--;if(in==0){break;}}if(in==0){continue;}String previous = expression.substring(in-1,i);if(isOperator(previous.charAt(0)) || previous.charAt(0)=='('){continue;}}if(operationNum.trim().length()>0){RNP.operationNum.push(operationNum.trim());}index = i+1;String operator = c+"";//如果操作符是'(',直接入栈if('('==c){RNP.operator.push(operator);//如果操作符是')',将'('操作符之后的全部出栈,入栈操作数,'(' ')'舍弃}else if(')'==c){while(true){String o = RNP.operator.pollFirst();if(o==null || "(".equals(o)){break;}RNP.operationNum.push(o);}//如果操作符是+-*/}else{String o = RNP.operator.peekFirst();if(o== null){//如果操作符栈为空,操作符直接入栈RNP.operator.push(operator);}else {char operator2 = o.charAt(0);//比较操作符,和操作符栈首的大小,如果操作符大,直接入栈if(operator2=='(' || operator2==')' || orderOperator(c,operator2)){RNP.operator.push(operator);//如果操作符栈首大,将操作符栈小于操作符的全部出栈,入栈操作数,最后改操作符入栈}else{while(true){if(o==null || o.charAt(0) =='('|| o.charAt(0) ==')'){break;}if(orderOperator(c, o.charAt(0))){break;}o = RNP.operator.pollFirst();RNP.operationNum.push(o);o = RNP.operator.peekFirst();}RNP.operator.push(operator);}}}}}String operationNum = expression.substring(index);if(operationNum.trim().length()>0){RNP.operationNum.push(operationNum.trim());}while(RNP.operator.size()>0){RNP.operationNum.push(RNP.operator.pollFirst());}// RNP.operationNum.addAll(RNP.operator);}//判断一个字符是否为运算符private static boolean isOperator(char c) {return c=='+' || c=='-' || c=='*' || c=='/';}//判断运算符顺序,true表示运算符operator1>operator2,false表示相等或小于private static boolean orderOperator(char operator1, char operator2){if((operator1=='*' || operator1=='/') && (operator2=='+' || operator2=='-')){ return true;}return false;}/*** 计算逆波兰式的值* @return*/private static double countRnp(){while(RNP.operationNum.size()>0){String s = RNP.operationNum.pollLast();//如果是操作符,取出栈顶的两个操作数,直接运算char operator = s.charAt(0);if(s.length()==1 && isOperator(operator)){String a = RNP.operator.pollFirst();String b = RNP.operator.pollFirst();if('+'==operator){double result = Double.parseDouble(b)+Double.parseDouble(a);RNP.operator.push(result+"");}else if('-'==operator){double result = Double.parseDouble(b)-Double.parseDouble(a);RNP.operator.push(result+"");}if('*'==operator){double result = Double.parseDouble(b)*Double.parseDouble(a);RNP.operator.push(result+"");}if('/'==operator){double result = Double.parseDouble(b)/Double.parseDouble(a);RNP.operator.push(result+"");}//如果是操作数,入栈}else{RNP.operator.push(s);}}double result = Double.parseDouble(RNP.operator.pollLast());return result;}/*** 计算逆波兰式的值(整数)* @return*/private static int intRnp(){while(RNP.operationNum.size()>0){String s = RNP.operationNum.pollLast();//如果是操作符,取出栈顶的两个操作数,直接运算char operator = s.charAt(0);if(s.length()==1 && isOperator(operator)){String a = RNP.operator.pollFirst();String b = RNP.operator.pollFirst();if('+'==operator){int result = Integer.parseInt(b)+Integer.parseInt(a);RNP.operator.push(result+"");}else if('-'==operator){int result = Integer.parseInt(b)-Integer.parseInt(a);RNP.operator.push(result+"");}if('*'==operator){int result = Integer.parseInt(b)*Integer.parseInt(a);RNP.operator.push(result+"");}if('/'==operator){int result = Integer.parseInt(b)/Integer.parseInt(a);RNP.operator.push(result+"");}//如果是操作数,入栈}else{RNP.operator.push(s);}}int result = Integer.parseInt(RNP.operator.pollLast());return result;}/*** 计算表达式的值* @param expression* @return*/public static double calculate(String expression){try{str2Rnp(expression);return countRnp();}catch(Exception e){e.printStackTrace();System.out.println("请检查表达式");return 0.0;}}/*** 计算表达式的值(整数)* @param expression* @return*/public static int intCalculate(String expression){try{str2Rnp(expression);return intRnp();}catch(Exception e){e.printStackTrace();System.out.println("请检查表达式");return 0;}}public static void main(String[] args) {String s= "53.12* 6/ ( -12-7.2)* -6 *( -4)*12*6/7.2-6";System.out.println(RNP.calculate(s));s = "((( -1+ 2 ) * -2) * -4)-9*( -1 + 2)";System.out.println(RNP.intCalculate(s));}}。

相关文档
最新文档