• 计算流图中的前必经节点


    《现代编译器的Java实现》中的一图,左边是流图,右边是必经节点树

    根据必经节点的算法写了程序验证了下。

    只是为了验证算法,并没有考虑最优算法,不过因为此流图足够简单,所以只迭代了两次即求出了结果。

    代码如下:

    Node类抽象图中的节点,Dominator类用来计算

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 
     4 public class Node {
     5     // 序号
     6     public int no;
     7     // 后接节点列表
     8     public List<Node> nextList = new ArrayList<Node>();
     9     // 前接节点列表
    10     public List<Node> preList = new ArrayList<Node>();
    11     // 初始前必经节点(全体节点)
    12     public List<Node> dominatorList = new ArrayList<Node>();
    13 
    14     public Node(int no) {
    15         this.no = no;
    16     }
    17 
    18     public void addNext(Node n){
    19         nextList.add(n);
    20         n.preList.add(this);
    21     }
    22     
    23     public String toString(){
    24         return no+"";
    25     }
    26 }
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class Dominator {
    
        public static void main(String[] args) {
            //初期化所有节点   并设置节点间连接关系
            List<Node> nodeList = getNodeList(12);
            // 计算前必经节点
            doDominator(nodeList);
            //打印必经节点列表
            printResult(nodeList);
    
        }
    
        // 打印必经结果
        public static void printResult(List<Node> nodeList) {
            for (int i = 0; i < nodeList.size(); i++) {
                Node node = nodeList.get(i);
                System.out.println("*******************");
                System.out.println("node" + (i + 1));
                printNodeListNo(node.dominatorList);
            }
        }
        
        //打印节点NO
        public static void printNodeListNo(List<Node> nodeList) {
            System.out.println("------");
            for (int i = 0; i < nodeList.size(); i++) {
                if (i != 0) {
                    System.out.print(",");
                }
                System.out.print(nodeList.get(i).no);
            }
            System.out.println();
        }
    
        // 计算必经节点
        public static void doDominator(List<Node> nodeList) {
            //迭代次数
            int n = 1;
            //判断状态是否稳定Flag
            boolean changed = true;
            while (changed) {
                System.out.println("迭代次数:" + n++);
                changed = false;
                for (int i = 0; i < nodeList.size(); i++) {
                    Node node = nodeList.get(i);
                    List<Node> lastDominatorList = new ArrayList<Node>();
                    lastDominatorList.addAll(node.dominatorList);
                    List<Node> temList = new ArrayList<Node>();
    
                    for (Node preNode : node.preList) {
                        List<Node> preDomList = preNode.dominatorList;
                        if (temList.isEmpty()) {
                            temList.addAll(preDomList);
                        } else {
                            temList.retainAll(preDomList);
                        }
                    }
                    temList.add(node);
                    int lastSize = lastDominatorList.size();
                    lastDominatorList.retainAll(temList);
                    if (lastSize != lastDominatorList.size()) {
                        node.dominatorList = temList;
                        changed = true;
                    }
                }
            }
        }
    
    
    
        //初期化所有节点   并设置节点间连接关系
        public static List<Node> getNodeList(int size) {
            List<Node> nodeList = new ArrayList<Node>(size);
            for (int i = 0; i < size; i++) {
                Node node = new Node(i + 1);
                nodeList.add(node);
            }
            Node node1 = nodeList.get(0);
            Node node2 = nodeList.get(1);
            Node node3 = nodeList.get(2);
            Node node4 = nodeList.get(3);
            Node node5 = nodeList.get(4);
            Node node6 = nodeList.get(5);
            Node node7 = nodeList.get(6);
            Node node8 = nodeList.get(7);
            Node node9 = nodeList.get(8);
            Node node10 = nodeList.get(9);
            Node node11 = nodeList.get(10);
            Node node12 = nodeList.get(11);
            // 节点之间关系设定
            node1.addNext(node2);
            //
            node2.addNext(node3);
            node2.addNext(node4);
            //
            node3.addNext(node2);
            //
            node4.addNext(node2);
            node4.addNext(node5);
            node4.addNext(node6);
            //
            node5.addNext(node7);
            node5.addNext(node8);
            //
            node6.addNext(node7);
            //
            node7.addNext(node11);
            //
            node8.addNext(node9);
            //
            node9.addNext(node8);
            node9.addNext(node10);
            //
            node10.addNext(node5);
            node10.addNext(node12);
            //
            node11.addNext(node12);
            //初期化前必经节点的列表
            for (int i = 0; i < nodeList.size(); i++) {
                nodeList.get(i).dominatorList.addAll(nodeList);
            }
            return nodeList;
        }
    
    }

    打印结果如下:

    迭代次数:1
    迭代次数:2
    *******************
    node1
    ------
    1
    *******************
    node2
    ------
    1,2
    *******************
    node3
    ------
    1,2,3
    *******************
    node4
    ------
    1,2,4
    *******************
    node5
    ------
    1,2,4,5
    *******************
    node6
    ------
    1,2,4,6
    *******************
    node7
    ------
    1,2,4,7
    *******************
    node8
    ------
    1,2,4,5,8
    *******************
    node9
    ------
    1,2,4,5,8,9
    *******************
    node10
    ------
    1,2,4,5,8,9,10
    *******************
    node11
    ------
    1,2,4,7,11
    *******************
    node12
    ------
    1,2,4,12

  • 相关阅读:
    意向锁
    锁升级
    使用SQL SERVER PROFILER 捕获和分析死锁
    用Go写一个聊天软件
    Js中的一个日期处理格式化函数
    javascript format 字符串 函数
    php 读取excel 时间列
    PHP发送post请求
    javascript getElementsByClassName扩展函数
    [ASP.NET] Session 详解
  • 原文地址:https://www.cnblogs.com/zwm512327/p/3536449.html
Copyright © 2020-2023  润新知