2009-09-03 6 views
0

Я пытаюсь рассчитать количество случаев успеха в рекурсивной функции в C#, но меня поражает тот факт, что моя переменная разделяется между всеми вызовами функций!Переменные, разделяемые в рекурсивных функциях

[обновление 2]

Более странным это время. делая так

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

перезагружается я до 0

делают этот

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

дает некоторые результаты (я не уверен, если это правильно)

[обновлено: полный код ]

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

при отладке переменной я принимаю значение 1, но он сбрасывается до 0 на следующей итерации !! , несмотря на использование

i = i + .... 

В чем проблема в том, что часть кода?

Спасибо

+0

Я думаю, вы должны создать простой репро, что высмеивает recurisve вызовов и удалить весь список, дерево и LINQ материала. Можете ли вы создать полный репро, который можно отрезать? – AnthonyWJones

+0

Я сделал, посмотрел исходный (редактировать) вопрос, но люди здесь попросили полный код, так как я, возможно, допустил некоторые ошибки в коде! – 0xFF

ответ

5
if (validWords.Count() == 0) 
    return 0; 

Должно быть

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

Кроме того, в общем, я лично считаю, что это лучше, глядя только отправить в одном элементе, в то время к рекурсивной фу nction.

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

Таким образом, вы не получите такую ​​же ошибку, как указано выше. Наконец, небольшая заметка.

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

можно записать в виде

w => w[0] = tree.Root 
+0

WAW справа! это было волшебство, на самом деле я выхожу из функции, не заканчивая цикл, но продолжая ее проверять все элементы! еще раз спасибо – 0xFF

3

Нет локальные переменных не вообще не разделяются между рекурсивными вызовами, вы должны рассмотреть некоторые другие проблемы проектирования, внутри и после цикла Еогеаспа, я не вижу никакого возвратного заявление, вы можете разместить полный код.

Хорошо, при отладке вы всегда будете наблюдать значение текущего метода i, отладка не очень хороша в рекурсивных функциях, мало что понять, вам придется переместить свой элемент управления в стек вызовов, чтобы фактически наблюдать значение ранее вызывающей текущей функции.

Я бы посоветовал вам вывести Trace или в файл журнала с вашим уровнем узла, который поможет вам выполнить фактическую отладку.

Пожалуйста, используйте ТРАССИРОВКИ заявление, как следовать ..

Trace.WriteLine(string.Format("{0},{1}",tree.Name,i)); 
+0

ok обновленный код – 0xFF

+0

Примите инструкцию Trace к выходным значениям, потому что отладка будет только и всегда отображать текущий метод i, поэтому вы никогда не будете наблюдать за более ранними значениями вызывающего абонента, см. Мой обновленный ответ в деталях. –

+0

это право! но в конце концов, у меня должна быть сумма всех звонков! это всегда 0, хотя – 0xFF

1

Локальные переменные не разделяют. То, что вы видите (сброс до 0), является значением i в (рекурсивно) вызванной функции validTreesFun (i получает значение 0 в начале функции).

Просто глядя на ваш код, я думаю, что возможная ошибка может быть в someTestHere - если это никогда не будет верно, тогда я останусь 0 во внешнем пространстве. В противном случае он должен увеличиваться на 1 для каждого истинного теста.

+0

тест возвращает true при отладке, но следующая итерация немедленно сбрасывается до 0, он не возвращает сумму – 0xFF

-1

Когда вы находитесь в режиме отладки, вы действительно видите, что i сбрасывается для вызова, но остается в желаемом значении для вызывающего.Например, стек:

validTreesFun --i = 0 для этого один

validTreesFun --i = х для этого, но если вы не идете TRow вызывающего стека, вы увидите 0, что хорошее значение в верхней части стека