tags:

views:

186

answers:

5

Hi, Is there any alternative way to recursion? The classs i am dealing are as follows TibrvMsg This is message class which contains fields of type TirvMsgField TibrvMsg can also contain TirvMsgField of type TibrvMsg.That means message can contain fields which are message themselves. I can use recursion to print all the fields.But i want to modify fields and add the to another Message. I am wondering if there is any alternative way to recursion?

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; 

} 

} The method getMsg() returns sample message.In getModMsg() i m using recursion and it works, that means i am able to print each and every field and subfield. Now in this method, i want to modify the field properties and update the message.Means method should return the modified message.Hence i m using :

field.id = id++; msg.updateField(field); This is not working.What i want now is to create a modified message using above functions.

+2  A: 

There is direct recursion where a method calls itself and indirect recursion where a method calls another method that somewhere down the line will call the original method. There isn't really any "alternative way to recursion" as recursion is just a concept.

npsken
Never heard the terms "direct" and "indirect" recursion before. I'm accustom to "recursive" functions and "mutually recursive" functions.
Stephen Swensen
"Direct" and "indirect" is the terminology I was taught, and it's also the terminology that Wikipedia uses, and as we all know, Wikipedia is the irrefutable source of everything factual: http://en.wikipedia.org/wiki/Recursion_(computer_science)#Direct_and_indirect_recursion
npsken
+1  A: 

I am still not understanding why you can't use recursion. But here is an idea. Almost anything written in recursion can be written using a stack and a loop. It can become really confusing using a loop but it will get that non-recursion. Hope this helps.

Amir Raminfar
+1  A: 

You can always use loops to do what you would do with recursion (otherwise languages which don't support recursion would not be able to do things certain things).

GreenMatt
To clarify, when you refer to languages that don't support recursion, you mean that they don't have tail-call optimisation. Clearly you can recurs in Java, but deep recursion can cause the call stack to grow. This is a limitation of the JVM and it's a limitation I truly wish they would address. If not for the sake of Java, for other languages such as Scala and Clojure.
dsmith
@dsmith There are some TC language which don't support recursion :-) Although (esp. now) rare, one example is [PEARL](http://en.wikipedia.org/wiki/PEARL_%28programming_language%29).
pst
dsmith: I think he means languages, like FORTRAN 77, that don't support recursion. In FORTRAN 77 it's a compiler error for a function to call itself, and since local variables are usually statically allocated (as opposed to stack allocated like in C), recursion is generally useless anyway.
Gabe
Yes, I mean languages which don't support recursion such as FORTRAN 77.
GreenMatt
Fair enough. I haven't written a line of FORTRAN since the late 80's and even then I wasn't doing anything real :-).
dsmith
@dsmith: I've not written anything serious in FORTRAN since 1990 myself...
GreenMatt
A: 

Kind of a vague question, but I feel like looking over the Composite design pattern might help you sort out what you need.

bemace
A: 

Your code modifies the field id as expected, the problem when you call updateField the action is on the chained message. What you need is to maintain the root or top message reference so you can add the fields to it.

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

If you still think you need to avoid recursion you can just use a stack and push the messages that need to be review.

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

Hope this helps and ,most important, solve your problem.

XecP277
Thank you .This really solves the problem.
Chirota
You might want to consider accepting this answer :).
XecP277