创建流程图的算法[一点指导??]

发布于 2024-11-07 06:41:19 字数 8035 浏览 0 评论 0原文

好吧,我知道这是一个模糊的问题,但我似乎被逻辑困住了......我想创建输入程序的流程图。我两天来一直在思考这个问题,但找不到最好的通用方法...所以我拼命地看着你们在这里帮助我...可能是我遗漏了一些小东西...

我有一个 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 文件的一部分....fir 代码片段:

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;   
}

现在我的做法是:

我有一个类阅读器它读取 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;
    //ArrayList&lt;dataObjects.Interface&gt; parentInterfaces=new ArrayList&lt;dataObjects.Interface&gt;();
    //dataObjects.Class[] classes=new dataObjects.Class[90];

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

        JOptionPane.showMessageDialog(null, "No of children of "+path+" is "+childNodes.getLength());
        for(int i=0;i&lt;=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;i&lt;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;i&lt;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;i&lt;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 && 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 && 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 一次只能保存一个节点可能是一个列表,但仍然可能会出现一些问题......有人可以改进它吗?

OK, I know it's a vague question, but I seem to be stuck with logic here...I want to create flow charts of the input programs. I hav been thinking about it since two days and can't get a best general approach...So i look desperately at you guyz to help me here....may be there is something small I am missing....

I have an xml file which contains the info about the given java program and looks like this:

<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>

Now this is a part of the xml file generated....fir the code snippet:

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;   
}

Now my way of doing it is:

I have a class reader which reades the xml file and one class createFLowChart which takes care of drawing. I start traversing the method node... If I find a statement, I call a function FundStatement which draws a retangular box and connects it with prv node. Doing this for If-else constructs without adding a lot of state boolean variables. So can any one guide me in this?

Now the prob is with if-else constructs. I can not find a simple way of traversig through the if -else trees and correctly make the edge connections among the nodes without adding a number of variables to contain the state info i.e an if has started or else started etc. Here is my approach but I am finding difficulty in the depth adjustments i.e, connecting the leaves of nested if-else statements :

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

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

        JOptionPane.showMessageDialog(null, "No of children of "+path+" is "+childNodes.getLength());
        for(int i=0;i<=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;i<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;i<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;i<childNodes.getLength();i++)
        {
            Node child=(Node)childNodes.item(i);
            traverse(child,parent);

        }
        parent.foundEndElse();

    }

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

    }
}

Now the three function called from the reader are:

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 && 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 && 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;
}

This works fine for the if else statements one level deep but deteriorates after that i understand that is because the globbal variable prvNode can hld only one node at a time may be a list ll do but still some problems may arise...Can any one improve it please??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不念旧人 2024-11-14 06:41:19

您可以采用递归方法来进行 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

这只是一个想法,除了记住二维平面上元素的布局之外,您还需要跟踪深度。但你应该先练习遍历算法,然后再适应布局。

You can do a recursive approach to do a A DFS traversal, for eg -

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

This is just an idea, you will need to keep a track of the depth as well, besides keeping in mind the layout of the elements on a 2-D plane. But you should workout the traversal algorithm first and then fit the layout later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文