2015-09-26 3 views
-1

Я хотел бы задать вопрос о том, как обращаться с зависимыми переменными.Зависимая переменная Loop C#

C1=MA(X,10) 
C2=MA(C1,10) 
C3=C2.Minus(C1) 
C4=MA(C3,10) 
Final=C4.Minus(C3) 

Иллюстрация: Конечная = C4.Minus (С3), я сохранить свои два параметра С4, С3.

C4(MA ok and firstTime in MA)--> C3(MA NotOK,not fstTime)---> C2(MA ok)--->C1(MA ok) 
         0-------------------> 10--------------> 10+10---->10+10+10=30 

Я создал класс на первый, чтобы получить все informtion каждой линии

public class IndicatorInform 
    { 
     char[] parenthesis = new []{'(',')'}; 
     char[] equal = new char[] { '=' }; 
     char[] comma = new char[] { ';' }; 
     char[] all = new char [] { '.','<'}; 


     string text=null; 
     string funcname=null; 
     string[] args=null; 

     public void IndicatorInform (string expression, out string text,out string funcName,out string [] args) 
     { 
      string [] parts= expression.Split(equal); 
      text = parts[0]; 
      if(parts[1].Contains(";")) 
      { 
       string[] subparts = parts[1].Split(parenthesis); 
       funcname = subparts[0]; 
       args = subparts[1].Split(comma); 
       if(args.Count.equal(2)) 
       { 
        funcarg = args[0]; 
        period = Convert.ToDouble(args[1]); 
       } 
      } 
      else 
      { 
       if (parts[1].Contains("Plus")) 
        funcname = "Plus"; 
       if (parts[1].Contains("Minus")) 
        funcname = "Minus"; 
       if (parts[1].Contains("Multi")) 
        funcname = "Multi"; 
       if (parts[1].Contains("Div")) 
        funcname = "Div"; 
       parts[1] = parts[1].Replace(funcname, ""); 
       args=parts[1].Split(all); 
      } 
     } 
     public double Shifts {get; set;} 
     public double period { get; set; } 
     public string Funcname { get; set; } 
     public string text { get; set; } 
     public string funcarg { get; set; } 
    } 

И тогда я создал справочник и начать бороться с зависимыми переменными

Dictionary<string,SubIndicator> Dico=new Dictionary<string,SubIndicator> ; 
     foreach (var line in richTextBox1.Lines) 
     { 
      SubIndicator SubInc = new SubIndicator(); 
      Dico.Add(SubInc.text,SubInc); 
     } 
     int incre=0; 
     double tempvalue=0; 
     foreach(string element in Dico.Keys) 
     { 
      string[] tempo=null; 
      if(Dico[element].text.Contains("Final")) 
      { 
       tempo=Dico[element].args; 
      } 
      else 
      { 
       if(tempo.Contains(Dico[element].text)) 
       { 
        if(Dico[element].Funcname.Contains("MA")) 
        { 
         if (incre.Equals(0)) 
         {tempvalue=Dico[element].period; 
         incre++;} 
         else 
         { 
          Dico[element].Shifts=tempvalue+Dico[element].period; 
          tempvalue =Dico[element].Shifts; 
         } 
        } 
        else 
        { 
         Dico[element].Shifts=tempvalue; 
        } 
       } 
      } 

Мой алгоритм работает для вышеуказанного случая. Но как заниматься более сложным делом, таким как

C1=MA(X,10) 
    C2=MA(X,20) 
    C3=MA(C1,5) 
    C4=MA(C2,10) 
    C5=MA(C3,15) 
    C6=MA(C4,10) 
    Final=C6.Minus(C5) 
C6(fst Time)---->C4--->C2   C5(fst Time)--->C3--> C1 
      0-->10+10-->10+10+20    0--> 15+5-->15+5+10 

Спасибо за помощь.

+0

Я не вижу в чем разница между первым и вторым примерами. Ca вы объясните дальше. Обычно эти проблемы типа требуют рекурсивного алгоритма для обработки более сложных входов. – jdweng

+0

@ jdweng В первом случае каждая строка зависит от предыдущей строки 'C4 -> C3 ---> C2 ---> C1', а не от второй. Мой алгоритм недостаточно умен, он может обрабатывать только строки за строкой. –

+0

Вы правы. Рекурсивный алгоритм - лучшее решение, не могли бы вы объяснить дальше? Спасибо –

ответ

0

Думаю, мне нужно написать более длинный ответ. Математические функции должны иметь двоичное дерево с элементами/узлами, которое является классом, который содержит левый узел, правый узел, значение и математический оператор. Элемент обычно является объектом класса и может быть значением в словаре. Узлы листьев будут содержать значения, в то время как узлы без листьев будут иметь операторы с либо левым узлом, либо правым узлом, либо как левым, так и правым узлом.

Math-функция связана с тем, что любая функция может быть разделена на левый и правый компоненты, такие как a = b + (c + d + e + f). b - левая компонента, а (c + d + e + f) - правая составляющая. Правильный компонент может быть разделен на левый и правый.

Вам нужен код, необходимый для двух частей. Первый заключается в анализе ввода в элементы. Вторая часть - вычисление результатов. Рекурсивная функция будет выполнять вычисления. Рекурсивные проверки, чтобы увидеть, содержит ли элемент левый и/или правый узлы и продолжает вызывать рекурсивную функцию до тех пор, пока не будет найден лист, содержащий значение. Затем восстанавливает стоп вызовов функций, заменяя математические операторы значением, возвращаемым из левого и правого компонентов.

+0

Прямо сейчас у меня есть класс IndicatorInform, который содержит всю информацию, такую ​​как левый узел, правый узел, значение и математический оператор. И словарь содержит все показатели. Я попробовал рекурсивную функцию. Но он не может выполнять работу, как вы упомянули выше, потому что эта функция не работает хорошо для сложного случая. –

+0

Как продолжать вызов рекурсивной функции до тех пор, пока не будет найден лист, содержащий значение. Затем восстанавливает стоп вызовов функций, заменяя математические операторы значением, возвращаемым из левого и правого компонентов. Это та часть, которую я не знаю. –

+0

@BlancoDDP Я только что нашел это после написания своего ответа по адресу http://stackoverflow.com/questions/32806814/recursive-algorithm-to-handle-depend-variables/32810622#32810622. Если вы посмотрите на мой ответ, это почти то же самое, что сказал jdweng, лучший способ приблизиться к этому - построить дерево и решить дерево. Сделайте быстрый взгляд и посмотрите, как приближается выражение и решается с помощью дерева, и вы поймете объяснение jdweng. – JTY