编译原理实验二-逆波兰式生成程序

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 编译原理实验二-逆波兰式生成程序,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、实验目的和要求:

1. 掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序

2. 要求利用逆波兰式生成算法编写程序,将从键盘上输入的算术表达式

(中缀表达式)转化成逆波兰式

二、实验平台:

   Java语言

三、主要实验内容及结果:

实验内容:

逆波兰表达式是算术表达式的后缀表示形式,逆波兰表达式生成算法的关 键在于比较当前运算符与栈顶运算符的优先关系,若当前运算符的优先级高于 栈顶运算符,则当前运算符入栈,若当前运算符的优先级低于栈顶运算符,则 栈顶运算符退栈。

程序代码:

import java.util.ArrayList;

public class InversePolish {
    // 存放运算符优先关系矩阵
   
private String[][] chars;
    // 存放运算符栈(index=0表示栈底,index=size()-1表示栈顶)
   
private ArrayList<String> stack;
    // 存放输入串
   
private ArrayList<String> inStr;
    // 存放输出串
   
private ArrayList<String> outStr;

    public static void main(String[] args) {

        InversePolish inversePolish = new InversePolish();
        String str = "a*(b+c)/d";
        inversePolish.init(str);
        inversePolish.mainFunc();
        for (String currentChar : inversePolish.outStr) {
            System.out.print(currentChar);
        }
    }

    private void mainFunc() {

        // 从左往右扫描中缀表达式
       
label1: for (String currentChar : this.inStr) {
            // 输入串为空?
           
if (currentChar.equals("#")) {
                // 栈为空?
               
while (true) {
                    if (this.stack.get(this.stack.size() - 1).equals("#")) {
                        break label1;
                    } else {
                        // 退栈输出
                       
this.outStr.add(this.stack.get(this.stack.size() - 1));
                        this.stack.remove(this.stack.size() - 1);
                        continue;
                    }
                }
            } else {
                // 运算符?
               
if (!this.isChar(currentChar)) {
                    // 输出
                   
this.outStr.add(currentChar);
                    continue;
                } else {
                    while (true) {
                        // 栈是否为空?
                       
if (this.stack.get(this.stack.size() - 1).equals("#")) {
                            // 入栈
                           
this.stack.add(currentChar);
                            continue label1;
                        } else {
                            // 比较当前运算符与栈顶运算符的优先级
                           
if (isFirst(currentChar)) {
                                // 入栈
                               
this.stack.add(currentChar);
                                continue label1;
                            } else {
                                // 当前运算符是')'
                               
if (currentChar.equals(")")) {
                                    while (true) {
                                        // 栈顶为'('
                                       
if (this.stack.get(this.stack.size() - 1).equals("(")) {
                                            // 退栈
                                           
this.stack.remove(this.stack.size() - 1);
                                            continue label1;
                                        } else {
                                            // 栈为空?
                                           
if (this.stack.get(this.stack.size() - 1).equals("#")) {
                                                System.out.println("ERROR");
                                            } else {
                                                // 退栈输出
                                               
this.outStr.add(this.stack.get(this.stack.size() - 1));
                                                this.stack.remove(this.stack.size() - 1);
                                                continue;
                                            }
                                        }
                                    }
                                } else {
                                    // 退栈输出
                                   
this.outStr.add(this.stack.get(this.stack.size() - 1));
                                    this.stack.remove(this.stack.size() - 1);
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void init(String str) {

        System.out.println(str);
        this.stack = new ArrayList<>();
        this.inStr = new ArrayList<>();
        this.outStr = new ArrayList<>();
        // 输入运算符优先关系矩阵8*7
       
this.chars = new String[][] { { ">", ">", "<", "<", "<", "<", ">" }, { ">", ">", "<", "<", "<", "<", ">" },
                { ">", ">", ">", ">", "<", "<", ">" }, { ">", ">", ">", ">", "<", "<", ">" },
                { ">", ">", ">", ">", ">", "<", ">" }, { "<", "<", "<", "<", "<", "<", "=" },
                { ">", ">", ">", ">", ">", "", ">" }, { "<", "<", "<", "<", "<", "<", "<" } };

        // 输入输入串
       
String[] temps = str.split("");
        for (String temp : temps) {
            this.inStr.add(temp);
        }
        this.inStr.add("#");
        // 输入运算符栈
       
this.stack.add("#");
    }

    // 运算符?
   
private boolean isChar(String currentChar) {

        return "+-*/↑()".contains(currentChar);
    }

    // 比较当前运算符与栈顶运算符的优先级
   
private boolean isFirst(String currentChar) {

        String stackChar = this.stack.get(this.stack.size() - 1);
        int x = "+-*/↑()#".indexOf(stackChar);
        int y = "+-*/↑()#".indexOf(currentChar);
        return this.chars[x][y].equals("<");
    }
}

运行结果:

 编译原理实验二-逆波兰式生成程序

四、心得体会

实现逆波兰式的算法,难度并不大,之所以要将看似简单的中缀表达式转换为复杂的逆波兰式,原因就在于这个简单是相对人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/128218.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!