在c ++中的分割算法 [英] Shunting-yard algorithm in c++
问题描述
我需要一个包含中缀字符串(如3 + 4 * 9)的函数,并将其转换为后缀(如4 9 * 3 +)。
I need a function that takes an infix string (like "3 + 4 * 9"), and convert it to postfix (like "4 9 * 3 +").
我把它工作,直到括号中的括号括起来。我一直在做这一整天,不能弄清楚我做错了什么 - 有人可能有一个新鲜的主意看到它,也许?我觉得我真的很亲近!
I got it working until you throw in parentheses within parentheses. I've been working on it all day and can't figure out what I'm doing wrong- can someone with a fresh mind see it, maybe? I feel like I'm really close!
谢谢!代码如下:
string ExpressionManager::infixToPostfix(string infixExpression)
{
cout << "itop Testing : " << infixExpression << endl;
string posnums = "0123456789";
string posops = "+-*/%(){}[]";
string onlyops = "+-/%*";
string space = " ";
string openbra = "([{";
string closebra = ")]}";
stack <string> nums;
stack <string> ops;
string output = "";
//check to make sure expression is valid
if (!(isBalanced(infixExpression)))
{
cout << "Infix Expression isn't balanced!" << endl;
return "invalid";
}
for (int i=0; i<infixExpression.size(); i++)
{
if ((posnums.find(infixExpression[i])!=string::npos) || (posops.find(infixExpression[i])!=string::npos) || (space.find(infixExpression[i])!=string::npos))
{}
else
{
cout << "Invalid character " << infixExpression[i] << " found." << endl;
return "invalid";
}
}
int numcount = 0;
int opcount = 0;
//Numbers vs. Operators
for (int i = 0; i < infixExpression.size(); i++)
{
if (posnums.find(infixExpression[i]) != -1)
{
while(infixExpression[i] != ' ')
{
if (i == (infixExpression.size()-1))
break;
i++;
}
numcount++;
}
if (onlyops.find(infixExpression[i]) != -1)
{
opcount++;
}
}
if (opcount == (numcount - 1))
{
}
else
{
cout << "Bad operators to numbers ratio!" << endl;
return "invalid";
}
//Get rid of proceeding whitespaces.
int safety = 0;
int net = infixExpression.size();
while (infixExpression[0] == ' ')
{
infixExpression.erase(0,1);
safety++;
if (safety>=net)
break;
}
//cout << "At this point, it is " << postfixExpression << endl;
//the fun part! Set up stacks
for (int i =0; i< infixExpression.size(); i++)
{
cout << "It gets hung up on character " << infixExpression[i] << endl;
if(openbra.find(infixExpression[i]) != -1)
{
string word = "";
word += infixExpression[i];
ops.push(word);
cout << "Pushing onto stack: " << word << endl;
}
else if(closebra.find(infixExpression[i]) != -1)
{
cout << "contents of remaining ops stack: "<< endl;
stack <string> temp;
temp = ops;
for (int j = 0; j < temp.size(); j++)
{
cout << "\t" << temp.top() << endl;
temp.pop();
}
while (openbra.find(ops.top()) == -1)
{
output += " " + ops.top();
cout << "Pushing from stack: " << ops.top() << endl;
ops.pop();
}
cout << "Pushing from stack: " << ops.top() << endl;
ops.pop();
}
else if (posnums.find(infixExpression[i]) != -1)
{
string word = "";
while (infixExpression[i] != ' ')
{
word += infixExpression[i];
i++;
if (i== infixExpression.size())
break;
}
output += " " + word;
}
else if (onlyops.find(infixExpression[i]) != -1)
{
if (ops.size() == 0)
{
string word = "";
word += infixExpression[i];
ops.push(word);
}
else
{
int o1p = 0;
int o2p = 0;
if ((infixExpression[i] == '+') || (infixExpression[i] == '-'))
o1p = 0;
else
o1p = 1;
if ((ops.top() == "+") || (ops.top() == "-"))
o2p = 0;
else
o2p = 1;
while ((ops.size() > 0) && (o1p <= o2p))
{
output += " " + ops.top();
cout << "(odd) Pushing from stack: " << ops.top() << endl;
if ((ops.top() == "+") || (ops.top() == "-"))
o2p = 0;
else
o2p = 1;
if (ops.size() > 0)
{
ops.pop();
}
else
{
break;
}
}
string word = "";
word += infixExpression[i];
ops.push(word);
}
}
}
while (output[0] == ' ')
{
output.erase(0,1);
}
return output;
}
推荐答案
此处是解决方案的(最后一个版本)。在一些步骤上,它使用Dijkstra的调度算法(在 traverse()
成员函数输出_
input _
表达式的符号形式,如果我们以正确的方式遍历它)。
Here is (the last version of) the solution. On some step it use Dijkstra's shunting yard algorithm (at the end of traverse()
member function output_
member contains reverse polish notation form of the input_
expression, if we traverse it in right way).
这篇关于在c ++中的分割算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!