[英]Shunting Yard Algorithm C++
I have written an attempt at Dijkstra's Shunting Yard Algorithm as part of a college project. 我曾尝试将Dijkstra的Shunting Yard算法作为大学项目的一部分。 All is working as expected but I am also required to show how the operators are sequenced after the process and I'm not sure how to do this, I believe the best way to do this is a Queue? 一切都按预期工作,但我也需要显示操作符在进程后如何排序,我不知道如何做到这一点,我相信最好的方法是队列? Does anyone have an idea of how this can be done? 有没有人知道如何做到这一点? My Code: 我的代码:
// 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;
}
Consider that a postfix expression shows unambiguously the evaluation order. 考虑后缀表达式明确显示评估顺序。 For example, the infix expression a+b*c
becomes abc*+
, and (a+b)*c
becomes ab+c*
. 例如,中缀表达式a+b*c
变为abc*+
,并且(a+b)*c
变为ab+c*
。
If you follow the expression evaluation of your code, you'll see that the order of evaluation can be represented by a postfix expression. 如果您遵循代码的表达式评估,您将看到评估的顺序可以由后缀表达式表示。
You can modify your code to output a postfix expression at the same time it's evaluating. 您可以修改代码以在评估的同时输出后缀表达式。 The basic idea is that whenever you push an operand (a number), you also append it to your postfix expression. 基本思想是每当你按下一个操作数(一个数字),你也可以将它附加到你的后缀表达式。 And whenever you perform an operation, you append the operator to the postfix expression. 每当执行操作时,都会将操作符附加到后缀表达式。 Parentheses, of course, are never added to the postfix. 当然,括号永远不会添加到后缀中。
So when you're evaluating (a+b)*c
, you do the following: 因此,当您评估(a+b)*c
,请执行以下操作:
You should be able to make these changes pretty easily in your code. 您应该能够在代码中轻松地进行这些更改。 Whenever you call numbers.push()
, also append the number to your postfix expression. 无论何时调用numbers.push()
,还要将数字附加到后缀表达式。 Whenever you call ops.pop()
to remove an operator (not a '('), append the popped operator to your postfix expression. When you've completed the evaluation, output the postfix expression. 每当你调用ops.pop()
来删除一个运算符(而不是'('))时,将弹出的运算符追加到你的后缀表达式。当你完成评估后,输出后缀表达式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.