views:

309

answers:

4

I'm trying to calculate the number of success cases within a recursive function in C#, but I'm astonished by the fact that my variable is shared between all the function calls!

[update 2]

More than strange this time. doing so

i = i + validTreesFun(tree.Nodes, newWords.ToList()) ;

resets i to 0

doing this

i = validTreesFun(tree.Nodes, newWords.ToList()) + i ;

gives some results (I'm not sure if it's correct)

[updated : the full code]

public static  int validTreesFun(List<Tree<char>> nodes, List<string> words)
    {
        int i = 0;
        if (nodes == null && (words == null || words.Count == 0 || (words.Count == 1 && words.First() == "")))
            return 1;
        else
            if (nodes == null)
                return 0;

        foreach (Tree<char> tree in nodes)
        {
            var validWords = words.Where(w => w.ToCharArray()[0] == tree.Root)
                .Select(w => w);
            if (validWords.Count() == 0)
                return 0;
            else
            {
                var newWords = validWords.Select(w => join( w.ToCharArray().Skip(1).ToArray()));
                i += validTreesFun(tree.Nodes, newWords.ToList());
            }
        }
        return i;
    }

when debuging the variable i take the value 1 but it resets to 0 on the next iteration!! despite the use of

i = i + ....

What is the problem in that piece of code?

Thank you

+3  A: 

No local variables are not at all shared between recursive calls, you should consider some other design problem, inside and after your foreach loop, I dont see any return statements, can you post full code.

Ok, in debugging you will always observe i's current method's value, debugging is not good in recursive functions, its little hard to understand, you will have to move your control down in Call Stack in order to actually observe value of earlier caller of current function.

I would advice you to output Trace or on log file with your level of node, that will help you actual debugging.

Please use TRACE Statement as follow..

Trace.WriteLine(string.Format("{0},{1}",tree.Name,i));
Akash Kava
ok full code updated
martani_net
Please Trace statement to output values, because debugging will only and always show current method's i, so you will never observe the earlier caller values, please see my updated answer in detail.
Akash Kava
that's right! but after all, at the end, i should have the sum of all the calls! it's always 0 though
martani_net
Only Trace will help you, there may be some logic which may never be true, as I cant understand your code so I dont know but some of conditions may be wrong. Putting Trace will help you whether the value of i is increasing at all or not.
Akash Kava
ok I got this from the tracea,0b,0c,0a,1c,0b,0b,0a,0a,0b,0a,0c,0a,0z,0
martani_net
+1  A: 

Local variables are not being shared. What you are seeing (the reset to 0) is the value of i in the (recursively) called function validTreesFun (i gets set to 0 at the start of the function).

Just looking at your code, I think a possible bug might be in someTestHere - if that is never true, then i will stay 0 in the outer scope. Otherwise it should increment by 1 for each true test.

Daren Thomas
the test returns true when I debug, but the next iteration it resets to 0 immediately, it doesnt return the sum
martani_net
A: 

When you are in debug mode, you indeed see that the i is reseted for the call but remain to the wanted value for the caller. Eg , the stack :

validTreesFun --i = 0 for this one

validTreesFun --i = x for this one, but if you do not go trow the calling stack, you will see 0, which is the good value for the top of the stack

Toto
+5  A: 
if (validWords.Count() == 0)
    return 0;

Should be

if (validWords.Count() == 0)
    continue;

Also, in general, I personally think it is nicer looking to only send in one element at a time to a recursive function.

public static  int validTreesFun(Tree<char> node, List<string> words)

That way you don't get the same kind of mistake like above. Finally, a minor note.

w => w.ToCharArray()[0] == tree.Root

can be written as

w => w[0] = tree.Root
Marcus Andrén
WAW right! that was magic, Acually I quit the function without finishing the loop, but with continue it scans all the elements! thank you again
martani_net