关于Java写逆波兰表达式堆栈操作简单实现
2017-07-10 20:57
447 查看
目的:
重新熟悉逆波兰表达式算法,通过Java实现逆波兰表达式从容更加深刻理解算法与编程之间的关系;重新熟悉堆栈,并用Java程序实现堆栈的操作。
验证方式:
图书馆查阅资料,手写计算逆波兰实现基本算法,电脑Java编程实现算法。
过程:
1. 通过读书,重新拾起逆波兰表达式算法的记忆,中缀表达式转化为后缀表达式,从而来实现计算器算法。
2. 中缀表达式转化为后缀表达式其实是运算表达式优先级的体现。
例:中缀表达式:1.a+b*c 2.(a+b)*c 3.(a+b*c)/(d-e)
后缀表达式:1.abc*+ 2.ab+c*3.abc*+de-/
由上例可以看出,优先级决定后缀表达式的书写。
3. 由具体算法实现逆波兰表达式:可建立两个堆栈,一个用来放置运算符(Sign),一个用来放置依次安排的后缀表达式(RPN)。A.如果进来的是数值,直接压到RPN中。B.如果进来的是‘(’,将它压入Sign。C.如果进来的是运算符:1.查看现在的Sign,如果它是‘(’,直接将运算符压入Sign;2如果不是,则看进来的运算符比Sign现在的顶部元素运算符的优先级是否更高,如果优先级高,将运算符压入Sign,如果不高于,则将Sign现在的顶部元素运算符取出压入到RPN中。C.如果进来的是‘)’,则在Sign中查找‘(’,并从Sign栈顶开始依次取出压入到RPN,直到找到‘(’,并将‘(’删除。
1. Java程序源码:
import java.util.Scanner;
public
class shuzu_RPN {
private
char[]list;//放置最开始输入的,被拆分之后的内容
private
char[]sign;//放置运算符
private
char[]rpnList;//放置逆波兰表达式
public
staticvoidmain(String[]
arge){
shuzu_RPNrpn=
newshuzu_RPN();
//通过键盘输入要要操作的中缀表达式
rpn.getEquation();
//将中缀表达式转化为后缀表达式
rpn.setRPN();
//输出表达式结果
rpn.printResult();
}
//获得整个算数表达式
public
voidgetEquation(){
System.out.println("请输入算数表达式:");
//键盘输入
Scannersc=
newScanner(System.in);
Stringstr=
sc.nextLine();
//获得输入内容后,将字符串内的空格都给消掉
str.replaceAll(" ",
"");
//将输入的字符串转换成字符放在list数组中
list = new
char[str.length()];
list =
str.toCharArray();
//输出一遍
System.out.println("您输入的算数表达式是:");
for(int
i = 0; i<list.length;
i++){
System.out.print(list[i]);
}
System.out.println();
}
//读取list,转化为逆波兰表达式
public
voidsetRPN(){
//创建一个字符,用来指针作用
char
x;
//将两个字符数组的长度限定
sign = new
char[list.length+1];
rpnList =
new char[list.length+1];
//指符号数组top
sign[0] =
'#';
/*在下面的运算中,rpn没加一个,rpnlen将指向下一位
而signlen指向的是当前sign的最高位*/
int
signlen = 0;
//指rpn数组top
int
rpnlen = 0;
for(int
i = 0; i <
list.length;
i++){
//依次读取字符,进行判断
x =
list[i];
switch(x){
case
'(':
//符号位加1
signlen++;
sign[signlen] =
x;
break;
case
')':
while(sign[signlen]!='('){
//依次将括号内容转入到rpnList中
rpnList[rpnlen] =
sign[signlen];
//RPN加位
rpnlen++;
//运算符号位减位
signlen--;
}
//将‘(’设置为空
signlen--;
break;
//接下来是算数运算符,加减乘除,当后一个优先级不高于前一个优先级,不出
case
'+':
case
'-':
for(int
j = signlen;
j >= 0; j--){
//+-的运算优先级比*/的低
if(sign[j] ==
'('||signlen == 0){
break;
}else{
//直接将现在的栈顶元素搞到rpnList中
rpnList[rpnlen] =
sign[j];
signlen--;
rpnlen++;
}
}
signlen++;
sign[signlen] =
x;
break;
case
'*':
case
'/':
for(int
j = signlen;
j >= 0; j--){
//运算优先级,*/的运算优先级高于+-
if(sign[j] ==
'('||sign[j] ==
'+'||sign[j] ==
'-'||signlen == 0){
break;
}else{
//把现在的顶部运算符拿出来
rpnList[rpnlen] =
sign[j];
signlen--;
rpnlen++;
}
}
signlen++;
sign[signlen] =
x;
break;
//遇到非运算符
default:
rpnList[rpnlen] =
x;
rpnlen++;
}
}
//当符号数组不为空,倒置放到rpn数组
while(signlen>0){
rpnList[rpnlen] =
sign[signlen];
signlen--;
rpnlen++;
}
}
[b]public
voidprintResult(){
System.out.println("生成的逆波兰表达式:");
for(int
i = 0; i <
rpnList.length;
i++){
System.out.print(rpnList[i]);
}
}
}
2. 运算结果:
请输入算数表达式:
((2+1)*(3-1))/(2-1)
您输入的算数表达式是:
((2+1)*(3-1))/(2-1)
生成的逆波兰表达式:
21+31-*21-/_
结果:
经过查阅资料,仔细验证,终于实现逆波兰表达式,并实现后进先出的堆栈。算法实现并不困难。最大的收获是及时发现自己出现的眼高手低的毛病。及时补漏,并以此为戒,是这次试验最大的收获。
这是很久之前写的一个简单的实现文档,没想到还留着.额...才疏学浅,请多多指教
重新熟悉逆波兰表达式算法,通过Java实现逆波兰表达式从容更加深刻理解算法与编程之间的关系;重新熟悉堆栈,并用Java程序实现堆栈的操作。
验证方式:
图书馆查阅资料,手写计算逆波兰实现基本算法,电脑Java编程实现算法。
过程:
1. 通过读书,重新拾起逆波兰表达式算法的记忆,中缀表达式转化为后缀表达式,从而来实现计算器算法。
2. 中缀表达式转化为后缀表达式其实是运算表达式优先级的体现。
例:中缀表达式:1.a+b*c 2.(a+b)*c 3.(a+b*c)/(d-e)
后缀表达式:1.abc*+ 2.ab+c*3.abc*+de-/
由上例可以看出,优先级决定后缀表达式的书写。
3. 由具体算法实现逆波兰表达式:可建立两个堆栈,一个用来放置运算符(Sign),一个用来放置依次安排的后缀表达式(RPN)。A.如果进来的是数值,直接压到RPN中。B.如果进来的是‘(’,将它压入Sign。C.如果进来的是运算符:1.查看现在的Sign,如果它是‘(’,直接将运算符压入Sign;2如果不是,则看进来的运算符比Sign现在的顶部元素运算符的优先级是否更高,如果优先级高,将运算符压入Sign,如果不高于,则将Sign现在的顶部元素运算符取出压入到RPN中。C.如果进来的是‘)’,则在Sign中查找‘(’,并从Sign栈顶开始依次取出压入到RPN,直到找到‘(’,并将‘(’删除。
1. Java程序源码:
import java.util.Scanner;
public
class shuzu_RPN {
private
char[]list;//放置最开始输入的,被拆分之后的内容
private
char[]sign;//放置运算符
private
char[]rpnList;//放置逆波兰表达式
public
staticvoidmain(String[]
arge){
shuzu_RPNrpn=
newshuzu_RPN();
//通过键盘输入要要操作的中缀表达式
rpn.getEquation();
//将中缀表达式转化为后缀表达式
rpn.setRPN();
//输出表达式结果
rpn.printResult();
}
//获得整个算数表达式
public
voidgetEquation(){
System.out.println("请输入算数表达式:");
//键盘输入
Scannersc=
newScanner(System.in);
Stringstr=
sc.nextLine();
//获得输入内容后,将字符串内的空格都给消掉
str.replaceAll(" ",
"");
//将输入的字符串转换成字符放在list数组中
list = new
char[str.length()];
list =
str.toCharArray();
//输出一遍
System.out.println("您输入的算数表达式是:");
for(int
i = 0; i<list.length;
i++){
System.out.print(list[i]);
}
System.out.println();
}
//读取list,转化为逆波兰表达式
public
voidsetRPN(){
//创建一个字符,用来指针作用
char
x;
//将两个字符数组的长度限定
sign = new
char[list.length+1];
rpnList =
new char[list.length+1];
//指符号数组top
sign[0] =
'#';
/*在下面的运算中,rpn没加一个,rpnlen将指向下一位
而signlen指向的是当前sign的最高位*/
int
signlen = 0;
//指rpn数组top
int
rpnlen = 0;
for(int
i = 0; i <
list.length;
i++){
//依次读取字符,进行判断
x =
list[i];
switch(x){
case
'(':
//符号位加1
signlen++;
sign[signlen] =
x;
break;
case
')':
while(sign[signlen]!='('){
//依次将括号内容转入到rpnList中
rpnList[rpnlen] =
sign[signlen];
//RPN加位
rpnlen++;
//运算符号位减位
signlen--;
}
//将‘(’设置为空
signlen--;
break;
//接下来是算数运算符,加减乘除,当后一个优先级不高于前一个优先级,不出
case
'+':
case
'-':
for(int
j = signlen;
j >= 0; j--){
//+-的运算优先级比*/的低
if(sign[j] ==
'('||signlen == 0){
break;
}else{
//直接将现在的栈顶元素搞到rpnList中
rpnList[rpnlen] =
sign[j];
signlen--;
rpnlen++;
}
}
signlen++;
sign[signlen] =
x;
break;
case
'*':
case
'/':
for(int
j = signlen;
j >= 0; j--){
//运算优先级,*/的运算优先级高于+-
if(sign[j] ==
'('||sign[j] ==
'+'||sign[j] ==
'-'||signlen == 0){
break;
}else{
//把现在的顶部运算符拿出来
rpnList[rpnlen] =
sign[j];
signlen--;
rpnlen++;
}
}
signlen++;
sign[signlen] =
x;
break;
//遇到非运算符
default:
rpnList[rpnlen] =
x;
rpnlen++;
}
}
//当符号数组不为空,倒置放到rpn数组
while(signlen>0){
rpnList[rpnlen] =
sign[signlen];
signlen--;
rpnlen++;
}
}
[b]public
voidprintResult(){
System.out.println("生成的逆波兰表达式:");
for(int
i = 0; i <
rpnList.length;
i++){
System.out.print(rpnList[i]);
}
}
}
2. 运算结果:
请输入算数表达式:
((2+1)*(3-1))/(2-1)
您输入的算数表达式是:
((2+1)*(3-1))/(2-1)
生成的逆波兰表达式:
21+31-*21-/_
结果:
经过查阅资料,仔细验证,终于实现逆波兰表达式,并实现后进先出的堆栈。算法实现并不困难。最大的收获是及时发现自己出现的眼高手低的毛病。及时补漏,并以此为戒,是这次试验最大的收获。
这是很久之前写的一个简单的实现文档,没想到还留着.额...才疏学浅,请多多指教
相关文章推荐
- c#3.0关于JSON简单操作的实用帮助类(泛型实现)
- Java项目中操作提示的简单实现
- 【用java简单的实现单链表的基本操作】
- 关于java 对xml 的简单读写操作
- java中关于I/O文件流的操作实现文件复制和打印功能
- c#3.5关于JSON简单操作的实用帮助类(泛型实现)
- 简单的用堆栈实现的表达式计算
- php简单实现算术表达式转换成逆波兰式,并求解
- java中cookie的操作(通过cookie实现简单的单点登录)
- 逆波兰表达式java实现
- c#3.5关于JSON简单操作的实用帮助类(泛型实现)
- java 关于IO的简单操作
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 用java实现简单的email正则表达式判断
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 关于java整形数组的两个简单操作
- Java程序操作Oracle两种方式之简单实现
- 用java实现简单的email正则表达式判断
- java 关于socket编程实现简单的c/s连接
- 使用栈计算多项表达式的简单实现--java