Алгоритм для создания блок-схемы [Небольшое руководство ??]

#java #xml #algorithm #logic #flowchart

#java #xml #алгоритм #Логические #блок-схема

Вопрос:

Хорошо, я знаю, что это расплывчатый вопрос, но, похоже, я застрял здесь с логикой…Я хочу создать блок-схемы входных программ. Я думал об этом два дня и не могу найти наилучшего общего подхода…Итак, я отчаянно прошу вас, ребята, помочь мне здесь …. может быть, есть что-то маленькое, чего мне не хватает….

У меня есть XML-файл, который содержит информацию о данной Java-программе и выглядит следующим образом:

 <Method modifier="publicstatic" type="void" name="main" >
    <FormalParameter modifier="" type="String[]" var_name="args" />
    <Throw>NullPointerException</Throw>
    <Throw>
        IndexOutofBoundException
    </Throw>
    <Field modifier="" type="int" name="x,y,z" />
    <Field modifier="" type="int" name=" sum[] " />
    <If>
        condition><![CDATA[(x==0)]]></condition>
        <Statement>
            <![CDATA[System.out.Println("I am in true")]]></Statement>
        <If>
            <condition><![CDATA[(y==2)]]></condition>
            <Statement>
                <![CDATA[System.out.Println("I am in
    true of y==2")]]></Statement>
        </If>
        <Statement>
            <![CDATA[System.out.prnitln("I am in
    true again")]]></Statement>
    </If>
    <else>
        <If>
            <condition><![CDATA[(x==2)]]></condition>
            <Statement>
                <![CDATA[System.out.println("I am in
    x==2 true")]]></Statement>
        </If>
        <else>
            <Statement>
                <![CDATA[System.out.println("I am in
     else 2")]]></Statement>
        </else>
    </else>
    <Statement>
        <![CDATA[c=b d]]></Statement>
    <Statement>
        <![CDATA[a=b c]]></Statement>
</Method>
  

Теперь это часть сгенерированного XML-файла …. для фрагмента кода:

 public static void main(String[] args) throws NullPointerException,IndexOutofBoundException {

    int x,y,z;
    int sum[]={1,2,3,4};
    if(x==0)
    {
        System.out.Println("I am in true");
        if(y==2)
        {
            System.out.Println("I am in true of y==2");
        }
        System.out.prnitln("I am in true again");
    }
    else if(x==2)
    {
        System.out.println("I am in x==2 true");
    }
    else
    {
        System.out.println("I am in else 2");
    }

    c=b d;
    a=b c;   
}
  

Теперь мой способ сделать это таков:

У меня есть класс reader, который считывает XML-файл, и один класс createFLowChart, который занимается рисованием. Я начинаю обход узла метода… Если я нахожу инструкцию, я вызываю функцию FundStatement, которая рисует прямоугольную рамку и соединяет ее с узлом prv. Выполнение этого для конструкций If-else без добавления большого количества логических переменных состояния. Итак, может ли кто-нибудь помочь мне в этом?

Теперь проблема с конструкциями if-else. Я не могу найти простой способ обхода деревьев if -else и корректного установления граничных соединений между узлами без добавления ряда переменных, содержащих информацию о состоянии, т.Е. if запущен или else запущен и т.д. Вот мой подход, но я нахожу трудности с настройками глубины, т.е. соединением листьев вложенных операторов if-else :

 public void traverse(String path,CreateFlowChart parent)
{
    xPath =  XPathFactory.newInstance().newXPath();
    XPathExpression expr;
    //ArrayListamp;<dataObjects.Interfaceamp;> parentInterfaces=new ArrayListamp;<dataObjects.Interfaceamp;>();
    //dataObjects.Class[] classes=new dataObjects.Class[90];

    try {
        expr = xPath.compile(path);
        Object result = expr.evaluate(document, XPathConstants.NODESET);
        NodeList MethodNodes = (NodeList) resu<
        NodeList childNodes=MethodNodes.item(0).getChildNodes();

        JOptionPane.showMessageDialog(null, "No of children of " path " is " childNodes.getLength());
        for(int i=0;iamp;<=childNodes.getLength()-1;i  )
        {

            Node node=childNodes.item(i);
            JOptionPane.showMessageDialog(null, "Found Child " node.getNodeName());
            traverse(node,parent);
        }


        } catch (XPathExpressionException e) {
        JOptionPane.showMessageDialog(null,"error: " e.toString());
        e.printStackTrace();
    }

}
private void traverse(Node root ,CreateFlowChart parent)
{

    if(root.getNodeName()=="If")
    {
        String condition="";
        NodeList childNodes=root.getChildNodes();
        for(int i=0;iamp;<childNodes.getLength();i  )
        {
            Node child=(Node)childNodes.item(i);
            if(child.getNodeName()=="condition")
            {
                Element ele=(Element)child;
                condition=ele.getTextContent();

            }
        }
        dataObjects.ControlStatements ifstmt=new dataObjects.ControlStatements(condition,null,true);
        parent.foundIf(ifstmt);
        NodeList childs=root.getChildNodes();
        for(int i=0;iamp;<childs.getLength();i  )
        {
            Node child=(Node)childs.item(i);
            traverse(child,parent);


        }

        parent.foundEndIf();


    }
    else if(root.getNodeName()=="else")
    {
        parent.foundElse();
        NodeList childNodes=root.getChildNodes();
        for(int i=0;iamp;<childNodes.getLength();i  )
        {
            Node child=(Node)childNodes.item(i);
            traverse(child,parent);

        }
        parent.foundEndElse();

    }

    else if(root.getNodeName()=="Statement")
    {
        parent.foundStatement(root.getTextContent());

    }
}
  

Теперь три функции, вызываемые из программы чтения, являются:

 public void foundIf(dataObjects.ControlStatements Ifstatement)
{
    JOptionPane.showMessageDialog(null,"Drawing If");
    graph.getModel().beginUpdate();
    try
    {
        Object v1 = graph.insertVertex(start, null, "If " Ifstatement.condition, 20, 20, 150,60,"Branch");
        if(isInIf==false amp;amp; isInElse==false)
        {
            JOptionPane.showMessageDialog(null,"Drawing normally");
            graph.insertEdge(start, null, "", currentNode,v1);
        }
        else if(isInIf==true)
        {
            JOptionPane.showMessageDialog(null,"Drawing inside a previous If");
            graph.insertEdge(start, null, "True", currentNode,v1);
            isInIf=false;
        }
        else if(isInElse==true)
        {
            JOptionPane.showMessageDialog(null,"Drawing inside a previous else");
            graph.insertEdge(start, null, "False", currentNode,v1);
            isInElse=false;
        }
        currentNode=(mxCell)v1;
        JOptionPane.showMessageDialog(null,"Pushing if node inside stack");
        lastIfNode.push(currentNode);
        isInIf=true;
    }
    finally
    {
        graph.getModel().endUpdate();
    }
}
public void foundElse()
{
    currentNode=lastIfNode.pop();
    isInElse=true;
}
public void foundStatement(String st)
{
    JOptionPane.showMessageDialog(null,"Drawing a statement");
    graph.getModel().beginUpdate();
    try
    {
        Object v1 = graph.insertVertex(currentNode, null, st, 20, 20, 150,60,"Statement");
        if(isInIf==false amp;amp; isInElse==false)
        {
            JOptionPane.showMessageDialog(null,"Drawing normally");
            graph.insertEdge(start, null, "", currentNode,v1);
        }
        else if(isInIf==true)
        {
            JOptionPane.showMessageDialog(null,"Drawing inside a prv If");
            graph.insertEdge(start, null, "True", currentNode,v1);
            isInIf=false;
        }
        else if(isInElse==true)
        {
            JOptionPane.showMessageDialog(null, "Drawing inside else");
            graph.insertEdge(start, null, "False", currentNode,v1);
            isInElse=false;
            reTraceIf=false;
        }
        if(reTraceIf==true)
        {
            JOptionPane.showMessageDialog(null, "Drawing false part");
            graph.insertEdge(start, null, "False", lastIfNode.pop(),v1);
            reTraceIf=false;
        }
        if(branchEnded==true)
        {
            JOptionPane.showMessageDialog(null, "Linking brancehs");
            graph.insertEdge(start, null, "", prvBranchNode,v1);
            branchEnded=false;
        }
        currentNode=(mxCell)v1;
    }
    finally
    {
        graph.getModel().endUpdate();
    }
}
public void foundEndIf()
{
    prvBranchNode=currentNode;
    isInIf=false;
    reTraceIf=true;
}
public void foundEndElse()
{
    branchEnded=true;
}
  

Это отлично работает для операторов if else на один уровень глубже, но ухудшается после этого, я понимаю, это потому, что глобальная переменная prvNode может одновременно управлять только одним узлом, может быть списком, который я сделаю, но все же могут возникнуть некоторые проблемы…Может ли кто-нибудь улучшить это, пожалуйста??

Комментарии:

1. Если вы делаете это не для того, чтобы узнать, как создать программу для рисования блок-схемы, вы могли бы рассмотреть возможность взглянуть на GraphViz ( graphviz.org ), и ваша программа преобразует ваш XML в формат graphviz и позволяет ему отображать чертеж.

2. хорошее предложение, я попробую……

Ответ №1:

Вы можете использовать рекурсивный подход для обхода DFS, например —

 1    For each line in block
2        If it is an if statement
3            Render condition in a Diamond shape
4            Get the statement block inside the if statement and go to #1
5        else 
6            Render it in a rectangle shape
  

Это всего лишь идея, вам также нужно будет отслеживать глубину, помимо учета расположения элементов на двумерной плоскости. Но вы должны сначала потренировать алгоритм обхода, а затем подогнать макет позже.

Комментарии:

1. да, это был мой подход .. сначала фактическая проблема с глубиной … и я думаю, что это может усложниться с включением операторов for-while do while-switch……..:(