【发布时间】:2016-11-03 23:01:49
【问题描述】:
分配规则:
- 必须具有单独的 Operator 类和包含转换方法的单独 PostFix 类。
- 从左到右评估。
- 运算符被放入堆栈中。
- 仅限二元运算符
- 独立的 Operator 类和 PostFix 类,其中 PostFix 包含 Conversion 方法。
- C#
我的问题:
如果所有/大部分等式都在括号中,则我的转换有效。仅当输入按操作顺序时,它才可以在没有括号的情况下工作。
我相信我只是没有正确检查优先级,但我不确定这是问题所在。我现在已经重写了我的转换方法 4 次,并且花了大约 25 小时在调试器中调整和运行该方法的不同迭代和谷歌搜索,但我只是不理解问题在我的代码中的位置。我在调试时看到了它,但我不确定我必须做些什么来修复它,所以我认为第三方的观点可能会有所帮助。
示例
输出不正确:
a=5+3/4-(9*8-1)*1 => a 5 3 + 4 / 9 8 * 1 - - 1 * =
should be a 5 3 4 / + 9 8 * 1 - - 1 * =
alpha = beta + gamma * delta => alpha beta gamma + delta * =
should be alpha beta gamma delta * + =
正确的输出:
a = ((((a+b)-c)*d)/(e+1)) => a a b + c - d * e 1 + / =
alpha = beta * gamma + delta => beta gamma * delta + alpha =
我的代码
算子类:
class Operator
{
private byte precedence = 1; //Precedence of operator over others
private char identity = 'x'; //the character behind the operator
/// <summary>
/// Creates an operator based on the passed character
/// </summary>
/// <param name="OperatorIn">Character definition of the operator</param>
public Operator(char OperatorIn)
{
identity = OperatorIn;
switch (OperatorIn)
{
case '*':
precedence = 2;
break;
case '/':
precedence = 2;
break;
case '(':
precedence = 3;
break;
case ')':
precedence = 3;
break;
case '=':
precedence = 3;
break;
case '+':
precedence = 1;
break;
case '-':
precedence = 1;
break;
default:
precedence = 0;
break;
}//switch
}//Operator(char)
/// <summary>
/// Retrieves the char representation of the operator
/// </summary>
/// <returns>Char representation of the operator</returns>
public char ToChar()
{
return this.identity;
}//ToChar()
/// <summary>
/// Returns the byte value of precedence of the operator
/// </summary>
/// <returns>byte value of precedence</returns>
public byte GetPrecedence()
{
return this.precedence;
}
}//Operator
转换方式:
public static string Convert(string infix)
{
#region original
Stack<Operator> OpStack = new Stack<Operator>();
String Postfix = String.Empty;
InfixPostfix.Operator Previous = new Operator('x'),
Current = null; //NextOp = new Operator(infix[infix.IndexOfAny(Ops, i)]);
char[] Ops = {'+','-','=','*','/'};
string term = String.Empty;
foreach(char c in infix)
{
if (Ops.Contains(c)) //if the char is one of the operator chars
{
Postfix += term + " "; //split term and add to output
while (OpStack.Count > 0) //While there's actually operators in the stack
{
Current = OpStack.Pop(); //Assign the operator as Current Operator
if (Current.GetPrecedence() < Previous.GetPrecedence()) //If Current Op is less priority than preceding Op
Postfix += Current.ToChar() + " "; //Output the character of the Op
else //If Current Op priority is higher than the previous
{
Previous = Current; //Store the current as previous to move on
OpStack.Push(Current); //Store current in stack
break; //Move to next char
}//else
}//while
OpStack.Push(new Operator(c)); //If stack is empty, push the operator
term = ""; // and reset the term to empty
}//if
else if (c == ')') //If the char is a close paren
{
Postfix += term + " "; //store the previous characters as a term in postfix
term = ""; //establish a new term
Previous = Current; //Set Current as the old Op
Current = OpStack.Pop(); //Get the new Current op
while (Current.ToChar() != '(') //Pop the stack until you get an open paren op
{
Postfix += Current.ToChar() + " "; //Add the term to the output string
//Previous = Current;
try
{
Current = OpStack.Pop(); //Try to pop another operator
}//try
catch(Exception) //If the stack is empty
{
return "Error! Mismatched parentheses!"; //Then there is a missing/misaligned paren
}//catch
}//while
}//else if
else if (c == '(') //If the op is an open paren
OpStack.Push(new Operator(c)); //store it
else if (c != ' ') //If it's an alphanumeric char,
term += c; //build a term with it
}//foreach
Postfix += term + " "; //add the last term to the output
while(OpStack.Count > 0) //If there are remaining ops on the stack,
{
Current = OpStack.Pop(); //pop them off
if (Current.ToChar() == '(' || Current.ToChar() == ')') //If there is a paren remaining
return "Error! Mismatched parentheses!"; // it's because of missing complement or misalignment
Postfix += Current.ToChar() + " "; //if regular op, add to output
}//while
return Postfix;
}
提前谢谢你!
【问题讨论】:
标签: c# postfix-notation infix-notation