2015-12-17 53 views
2

添加了另一個示例。如何解析從末尾開始的字符串C++

我有一個數學表達式,如cos(pi * cos(pi * sin(pi * y))),我想解決它。

我認爲解析它的最好方法是從字符串的末尾開始。

所以,在上面的表達式中:

  1. I = SIN(PI * Y)
  2. I = COS(PI * I)
  3. I = COS(PI * I)

我要去添加另一種表達爲例如: COS(PI *(平均(X,X)* Y))

這應該是這樣進行評估:

  1. I = AVG(X,X)
  2. I = I * Y
  3. 我= COS(PI * I)

你怎麼看呢?你能幫我實現一個代碼嗎?

在此先感謝

+0

你是什麼意思的「解決它」?數字,象徵性? – CroCo

+2

我認爲你應該使用遞歸來解析這種表達式 –

+0

「解決它」我的意思是得到一個整數,它是評估的結果,我應該給變量x和y一個值,我知道。 – Elena

回答

0

編輯:基本情況的改善。

這僅僅是一些僞代碼,但這個想法應該工作:

int ParseAndCalculate(string input) 
{ 
    if (input.DoesConvertToSomeIntegerWork()) 
     return input.ConvertToSomeInteger(); 

    string actionRequired = GetActionFromString(input, "("); 
    int tempIndex = input.LocationOfFirst("("); 
    int tempResult = ParseAndCalculate(input, tempIndex, input.Length -1); 
    tempResult = PerformRequiredAction(tempResult, actionRequired); 

    return tempResult; 
} 

不知道你應該在基本情況返回的內容。也許算出那裏的實際價值是什麼?

+0

對不起,但我不明白這個僞代碼如何指導OP。爲什麼函數返回'int'?沒有規則,想出一個好的僞指令是非常困難的。 – CroCo

+0

那麼,@CroCo,它給出了一些方法的基本思路。是的,它可能需要返回'long','double'或甚至一個'string'。是的,語法類似於'C#',是的,我認爲分隔符是'('和')'。但由於這些問題大部分都可以在其他子功能中完成,所以這個想法保持不變。因此*僞代碼* ... –

0

如果你想編寫一個C/C++程序來解析上述的數學表達式,你可以自己編寫一個自上而下的解析器,或者你可以看看GNU Bison

Bison是一個語法分析器生成器,它恰好與example一樣,與您的問題非常接近。

使用它的好處是你不需要關心實際的解析例程,但可以專注於語法規範和數學函數回調。我不得不承認,進入Bison並將其融入到構建過程中可能是一項非常努力的工作。我無法分辨它是否對您的情況非常有用,但至少它是解決此類任務時使用的既定且強大的工具。

它也可以用於評估「正確」順序的表達式,因爲它支持運算符優先級定義。

3

我有一個數學表達式,如cos(pi * cos(pi * sin(pi * y))) 我想解決它。

不,你想評估它。解決告訴你什麼是事實的條件。評估它只是給你一個結果值。

我認爲解析它的最好方法是從字符串的末尾開始。

解析像這樣的表達式的傳統方法是使用遞歸下降。這是更一般和更容易實施。控制流看起來是這樣的:

  • cos(一個 ...

    • 其中一個 = pi*cos( ...

      • 其中 = pi*sin(ç ...

        • 其中Ç = pi * y

          現在你可以評估pi * y,並返回值C

        ...現在你有Ç,您可以評估pi * sin(C),並返回

      的價值...現在你有的價值,你可以評估pi * cos(B),返回值作爲一個

    ...現在您的值爲A,您可以評估cos(A),然後就完成了。

這正是C表達式cos(M_PI * cos(M_PI * sin(M_PI * y)))的工作方式(假設π的常見但非標準常量)。

它是評價大致從右到左(實際上內部至外),但仍左到右。爲了清晰起見,我們只標記了臨時值。

該控制流程往往只是變成一棵樹一樣

[cos of _] 
     | 
    [pi * _] 
      | 
    [cos of _] 
      | 
     [pi * _] 
       | 
      [sin of _] 
        | 
       [pi * y] 

但很明顯,除非你需要保存的樹後,你可以只評估一次的結果。 (請注意,這個不平衡的樹仍然是一棵樹,它只是因爲表達式嵌套的方式而退化)。

...你怎麼看待它?

你的解決方案的問題是,它打破了不同的嵌套結構,例如。

cos(sin((pi * x) + y) + sin(y + (pi * x))) 

不能簡單地從右到左進行評估。

你能幫我實施一下代碼嗎?

將字符串處理(標記化)從解析和評估中分離出來。獨立推理你的字符串處理和你的數學要容易得多。

+0

由於OP似乎對解析器的知識非常有限,因此指向可用的解析器生成器將會很有趣。我使用antlr for Java,它沒問題。我曾嘗試一次(幾年前)Boost.Spirit,但錯誤消息讓我停止使用它。你對C++有什麼建議嗎? – Jens

+0

老實說,對於這種簡單的表情,似乎直接實施就是要走的路 - 至少作爲一種學習練習。我之前使用的詞法分析器/解析器系統可能比C++所需的學習曲線更多,如果您不瞭解基本知識,那麼錯誤和文檔可能會更難理解。如果任何人有一個初學者友好的建議,但會受到好評。 – Useless

+0

@非常感謝您的回答,但我仍然對此有所懷疑。你能幫我至少一點點來實現這些代碼嗎?非常感謝你。 – Elena