在java中递归的另一种方法

时间:2010-10-22 03:01:56

标签: java recursion

有没有其他替代方法来递归?我正在处理的课程如下 TibrvMsg 这是包含 TirvMsgField 类型字段的邮件类 TibrvMsg还可以包含TibrvMsg类型的TirvMsgField。这意味着消息可以包含消息本身的字段。 我可以使用递归打印所有字段。但我想修改字段并添加到另一个消息。我想知道是否有任何其他的递归方式?

import com.tibco.tibrv.*; 

public class ShowMsg { 

static TibrvMsg modMsg =new TibrvMsg(); 
static int id = 0; 
public static void main(String[] args) throws TibrvException{ 

    TibrvMsg msg = getMsg(); 
    TibrvMsg modMsg = getModMsg(msg); 
    //System.out.println(modMsg); 
    for(int i=0;i<modMsg.getNumFields();i++){ 
        TibrvMsgField field = modMsg.getFieldByIndex(i); 
        System.out.println(field.name+"-------"+field.id); 
    } 


} 

public static TibrvMsg getMsg(){ 
    TibrvMsg msg = new TibrvMsg(); 
    try{ 
    TibrvMsg subMsg = new TibrvMsg(); 
    subMsg.add("S1","43333"); 
    subMsg.add("S2","7377773"); 
    subMsg.add("S3","8388883"); 
    //subMsg.add("SUBSUB", subSubMsg); 

    msg.add("Field1", "JJSJJS"); 
    msg.add("Field2", "JDSKJKS"); 
    msg.add("Field3", "9299399"); 
    msg.add("Field4", "HHJJSJJSJ"); 
    msg.add("SUB",subMsg); 
    } 
    catch(TibrvException rv){ 
        System.out.println(rv); 
    } 
    return msg; 
} 



public static TibrvMsg getModMsg(TibrvMsg msg){ 

    try{ 
        int total = msg.getNumFields(); 

        for(int i=0;i<total;i++){ 
        TibrvMsgField field = msg.getFieldByIndex(i); 
        if(field.type==TibrvMsg.MSG){ 
             getModMsg((TibrvMsg)field.data); 
        } 
        else{ 

            field.id = id++; 
            msg.updateField(field); 

        } 

    } 
    } 
    catch(TibrvException rv){ 
    System.out.println(rv);  
    } 

    return msg; 

} 

} 方法getMsg()返回示例消息。在getModMsg()中我使用递归并且它工作,这意味着我能够打印每个字段和子字段。现在在这个方法中,我想修改字段属性并更新消息.Means方法应该返回修改后的消息.Hence我使用:

field.id = id ++; msg.updateField(场); 这不起作用。我现在想要的是使用上述功能创建修改后的消息。

5 个答案:

答案 0 :(得分:3)

有一个直接递归,其中一个方法调用自身和间接递归,其中一个方法调用另一个方法,在该行的某个地方将调用原始方法。由于递归只是一个概念,因此实际上没有任何“递归递归方式”。

答案 1 :(得分:1)

我仍然不明白为什么你不能使用递归。但这是一个想法。几乎所有用递归编写的东西都可以使用堆栈和循环编写。它可能会变得非常混乱使用循环,但它会得到非递归。希望这可以帮助。

答案 2 :(得分:1)

您总是可以使用循环来执行递归操作(否则不支持递归的语言将无法执行某些操作)。

答案 3 :(得分:1)

您的代码按预期修改了字段ID,当您调用updateField时,该操作位于链接消息上。您需要的是维护根或顶部消息引用,以便您可以向其添加字段。

private static class Context {
    private int sequence ; // to avoid using the static var id (Thread-Safety)
    private TibrvMsg head ; // The message we want to receive the childs data
    private TibrvMsg current ; // Message to work in the level of recursion
}

public static TibrvMsg getModMsg(TibrvMsg message) {
    Context context = new Context() ;
    context.sequence = 0;
    context.head = message ; // can be a new message ;)
    context.current = message ;

    return getModMsg(context) ;
}

public static TibrvMsg getModMsg(Context context) {
    TibrvMsg current = context.current ;
    int total = current.getNumFields() ;

    for(int idx = 0; idx < total; idx++)
    {
        TibrvMsgField field = current.getFieldByIndex(idx); 
        if (field.type == TibrvMsg.MSG) { 
            context.current = (TibrvMsg)field.data ; 
            getModMsg(context) ;
        } else { 
            field.id = context.sequence++; 
            context.head.updateField(field); 
        }
    } 

    return current ;
}

如果你仍然认为你需要避免递归,你可以使用一个堆栈并推送需要审查的消息。

public static TibrvMsg getModMsg(TibrvMsg message) {
    Stack<TibrvMsg> stack = new Stack<TibrvMsg>() ;
    stack.push(message);

    while (!stack.isEmpty()) 
    {
        TibrvMsg current = stack.pop() ;
        int total = current.getNumFields() ;

        for(int idx = 0; idx < total; idx++)
        {
            TibrvMsgField field = current.getFieldByIndex(idx); 
            if (field.type == TibrvMsg.MSG){ 
                stack.push((TibrvMsg)field.data); 
            } else { 
                field.id = id++; 
                message.updateField(field); 
            }
        } 
    }

    return message ;
}

希望这有帮助,最重要的是,解决您的问题。

答案 4 :(得分:0)

有点模糊的问题,但我觉得查看Composite设计模式可能会帮助你理清你需要的东西。