簡體   English   中英

Shunting Yard算法C ++

[英]Shunting Yard Algorithm C++

我曾嘗試將Dijkstra的Shunting Yard算法作為大學項目的一部分。 一切都按預期工作,但我也需要顯示操作符在進程后如何排序,我不知道如何做到這一點,我相信最好的方法是隊列? 有沒有人知道如何做到這一點? 我的代碼:

// Finding operators 
int operators(char op){ 
    if(op == '+'||op == '-') 
    return 1; 
    if(op == '*'||op == '/') 
    return 2; 
    return 0; 
} 

// The maths
int maths(int a, int b, char op){ 
    switch(op){ 
        case '+': return a + b; 
        case '-': return a - b; 
        case '*': return a * b; 
        case '/': return a / b; 
    } 
  return 0;
} 

// Returning value of expression
int evaluate(string tokens){ 
    int i; 

    // stack to store integers and operators. 
    stack <int> numbers;  
    stack <char> ops; 

    for(i = 0; i < tokens.length(); i++){ 

        // if token blank, skip 
        if(tokens[i] == ' ') 
            continue; 

        // if token '(' add to stack
        else if(tokens[i] == '('){ 
            ops.push(tokens[i]); 
        } 

        // if token is a number, add to stack
        else if(isdigit(tokens[i])){ 
            int val = 0; 

            // single or double digit number.
            while(i < tokens.length() && 
                        isdigit(tokens[i])) 
            { 
                val = (val*10) + (tokens[i]-'0'); 
                i++; 
            } 

            numbers.push(val); 
        } 

        // if token ')', solve entire brace. 
        else if(tokens[i] == ')') 
        { 
            while(!ops.empty() && ops.top() != '(') 
            { 
                int val2 = numbers.top(); 
                numbers.pop(); 

                int val1 = numbers.top(); 
                numbers.pop(); 

                char op = ops.top(); 
                ops.pop(); 

                numbers.push(maths(val1, val2, op)); 
            } 

            // pop opening brace. 
            ops.pop(); 
        } 

        // Current token is an operator. 
        else
        { 

            while(!ops.empty() && operators(ops.top()) 
                                >= operators(tokens[i])){ 
                int val2 = numbers.top(); 
                numbers.pop(); 

                int val1 = numbers.top(); 
                numbers.pop(); 

                char op = ops.top(); 
                ops.pop(); 

                numbers.push(maths(val1, val2, op)); 
            } 

            // Push current token to 'ops'. 
            ops.push(tokens[i]); 
        } 
    } 

    //Do remaining operations 
    while(!ops.empty()){ 
        int val2 = numbers.top(); 
        numbers.pop(); 

        int val1 = numbers.top(); 
        numbers.pop(); 

        char op = ops.top(); 
        ops.pop(); 

        numbers.push(maths(val1, val2, op)); 
    } 

    // Top of 'numbers' contains result, return
    return numbers.top(); 
} 

int main() { 
    cout << evaluate("10 + 10 * 10") << "\n"; 
    cout << evaluate("3 + 4 * 2 + ( 23 - 5 )") << "\n"; 
    cout << evaluate("100 * ( 2 + 12 )") << "\n"; 
    cout << evaluate("100 * ( 5 + 8 ) / 7") << "\n"; 
    return 0; 
}  

考慮后綴表達式明確顯示評估順序。 例如,中綴表達式a+b*c變為abc*+ ,並且(a+b)*c變為ab+c*

如果您遵循代碼的表達式評估,您將看到評估的順序可以由后綴表達式表示。

您可以修改代碼以在評估的同時輸出后綴表達式。 基本思想是每當你按下一個操作數(一個數字),你也可以將它附加到你的后綴表達式。 每當執行操作時,都會將操作符附加到后綴表達式。 當然,括號永遠不會添加到后綴中。

因此,當您評估(a+b)*c ,請執行以下操作:

  1. 將'('推到運算符堆棧上。
  2. 將'a'推入操作數堆棧,並在后綴表達式中附加'a'。
  3. 將“+”推入運算符堆棧。
  4. 將'b'推入操作數堆棧,並將'b'追加到后綴表達式中。
  5. 你遇到')'。 從運算符堆棧彈出'+'並附加到您的后綴表達式。 從操作數堆棧中彈出“a”和“b”,執行操作,並將結果推回到運算符堆棧。
  6. 將'*'推送到運算符堆棧。
  7. 將“c”按到操作數堆棧,然后附加到后綴表達式。
  8. 你在表達的最后。 從運算符堆棧彈出'*',附加到后綴表達式,彈出操作數和求值。

您應該能夠在代碼中輕松地進行這些更改。 無論何時調用numbers.push() ,還要將數字附加到后綴表達式。 每當你調用ops.pop()來刪除一個運算符(而不是'('))時,將彈出的運算符追加到你的后綴表達式。當你完成評估后,輸出后綴表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM