簡體   English   中英

在三元字符串中處理一元非運算符的調車碼算法

[英]Shunting yard algorithm with handling unary NOT operator in Ternary string

我目前正在編寫三元邏輯字符串的中綴到前綴傳輸。 具體來說,字符串中只有三個操作數 T、F、U 和三個運算符 AND、NOT、OR 和括號。 Not 的優先級高於 AND,OR 和 AND OR 具有相同的優先級。 這是我從原始調車場算法更改的代碼,但某些輸入的翻譯不正確

string Infix_To_Prefix(string expression){
    string prefix_expression = "";
    stack<char> char_stack;
    unordered_map<char,int> Precendence;
    Precendence['~'] = 2;
    Precendence['|'] = 1;
    Precendence['&'] = 1;

    for(int i=0;i<expression.size();i++)
    {
        char token = expression[i];
        if(isOperator(token))
        {
            while(!char_stack.empty() and isOperator(char_stack.top()))
            {
                if(Precendence[token] < Precendence[char_stack.top()])
                {
                    prefix_expression+=char_stack.top();
                    char_stack.pop();
                    continue;
                }
                break;
            }
            char_stack.push(token);
        }

        else if(token == '(')
        {
            char_stack.push(token);
        }
        else if(token == ')')
        {
            while(!char_stack.empty() and char_stack.top() != '(')
            {
                prefix_expression+=char_stack.top();
                char_stack.pop();
            }
            char_stack.pop();
        }
        else if(isOperand(token))
        {
            prefix_expression+=token;
        }

    }
    while(!char_stack.empty())
    {
        prefix_expression+=char_stack.top();;
        char_stack.pop();
    }
    return prefix_expression;
}

在您的代碼中,您檢查優先級:

if(Precendence[token] < Precendence[char_stack.top()])
{
    prefix_expression+=char_stack.top();
    char_stack.pop();
    continue;
}

在你在評論中引用的程序中,肯定不是原來的調車場實現,代碼是

if ((isAssociative(token, LEFT_ASSOC) && 
        cmpPrecedence(token, stack.peek()) <= 0) || 
    (isAssociative(token, RIGHT_ASSOC) && 
        cmpPrecedence(token, stack.peek()) < 0)) 
{
    out.add(stack.pop());   
    continue;
}

因此,您的測試與提供的代碼在右關聯運算符的情況下所做的相同,這就是您的代碼所做的。 如果您希望您的運算符是左關聯的,您需要將<更改為<= ,就像您正在改編的代碼中一樣。

但是,這對於一元運算符不起作用,因為一元運算符需要是右結合的,至少在調車場算法的實現中通常顯示的簡單視圖中是這樣。

更准確地說,一元運算符應該始終被壓入堆棧,而不管其前面的運算符的優先級如何; 由於它不使用右手運算符,因此它不與前一個運算符競爭,只與后一個運算符競爭。 因此,作為傳入標記的一元運算符必須比堆棧上的任何運算符具有更高的優先級,盡管堆棧上的一元運算符可能具有也可能不具有比傳入運算符標記更高的優先級。 如果一元運算符是最高優先級運算符,則使其右結合將產生這種效果。 所以我認為特殊情況的一元運算符更干凈,就像你已經用括號做的那樣:

for (char token: expression)  {
  if (token == '(' || token == '~')
    char_stack.push(token);
  else if (isOperator(token)) {
    while (!char_stack.empty()
           and isOperator(char_stack.top())
           and Precendence[token] < Precendence[char_stack.top()]) {
        prefix_expression+=char_stack.top();
        char_stack.pop();
    }
    char_stack.push(token);
  }
  else if(token == ')') {
    while(!char_stack.empty() and char_stack.top() != '(') {
      prefix_expression+=char_stack.top();
      char_stack.pop();
    }
    char_stack.pop();
  }
  else if(isOperand(token))
    prefix_expression+=token;
}

彈出堆棧的各種循環之間的相似性應該建議簡化,這通常在運算符優先級解析器中實現(Shunting Yard 就是一個例子)。

暫無
暫無

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

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