2015-09-26 186 views
-1

我想問一個關於如何處理因變量的問題。從屬變量循環C#

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

舉例說明:最終= C4.Minus(C3),我保存它的兩個參數C4,C3。

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 

我創建了一個類,在第一個拿到每一行的所有PVC門

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

然後我創建了一個Dictonary,並開始應對因變量

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

我不明白第一個和第二個例子有什麼區別。你可以進一步解釋。通常這些類型的問題需要遞歸算法來處理更復雜的輸入。 – jdweng

+0

@ jdweng第一種情況,每行依賴於前一行'C4 - > C3 ---> C2 ---> C1',而不是第二行。我的算法不夠智能,只能逐行處理。 –

+0

你說得對。遞歸算法是更好的解決方案,你能否進一步解釋?謝謝 –

回答

0

我想我需要寫一個更長的答案。數學函數需要有一個元素/節點的二叉樹,它是一個包含左節點,右節點,值和數學運算符的類。該元素通常是一個類對象,可以是字典中的值。葉子節點將包含值,而非葉子節點將具有左節點,右節點或左右節點的運算符。

數學函數是相關聯的,所以任何函數都可以分成左和右分量,如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