我需要将 array_name[i, i*k, ik] 之类的表达式转换为反向波兰表示法。我基本上在做的是尝试将这样的表达式翻译:
if(array_name[i, j+k]>=a+b) array_name[i, j*k] = a+2; else x = a / b;
使用正则表达式转换为 RPN。我已经有一个非常丑陋的巨大正则表达式,它匹配:if, else, + - * / = == ( ) <= >= < > !=
以及匹配此模式的所有单词:[a-zA-z][a-zA-z0-9_]*
。而且我还有将中缀算术表达式转换为 RPN 的代码。这里是:
/// <summary>
/// Returns the collection of all the lexemes of the expression
/// using Regex.
/// The Regex created works fine with 'if else' constructions and is good
///with
///any variable name possible in C#, with arithmetical expressions,
///like +, -, /, and all the boolean operators.
/// </summary>
/// <param name="input">String expression in infix notation.</param>
/// <returns>Collection of all the lexemes of the expression</returns>
private static MatchCollection GetMatchCollection(string input)
{
var rx =
new Regex(
@"/\bif\b|\belse\b|\(|\)|\+|\-|\*|\<=|\>=|\\|\>|\<|(?<![!=])[!=]=(?!=)|([a-zA-Z][a-zA-z0-9_]*)|(\d+\.?\d*)|(?<!=)=(?!=)|\/|/^/g");
return rx.Matches(input);
}
/// <summary>
/// Translates the infix expression into RPN
/// </summary>
/// <param name="input">String expression in infix notation.</param>
/// <returns>RPN expression</returns>
public static string Translate(string input)
{
var mc = GetMatchCollection(input);
var id = new Regex(@"[a-zA-z][a-zA-z0-9_]*"); // regex for identifiers
var num = new Regex(@"\d+\.?\d*"); // regex for decimals
var skobki = new Regex(@"\(|\)"); // regex for braces
object[] operators =
{
"(", ")", "else", "*", "/", "+", "-", "=", "<", ">", "<=", ">=", "==", "!=", "&&",
"||", "if"
}; // operators by priority
var opers = new Regex(@"\(|\)|\+|\-|\*|\/|<=?|>=?|!=|=|&&|\|\|\bif\b|\belse\b"); // regex for operators
var stOper = new Stack();
var expr = new ArrayList();
foreach (Match m in mc)
{
var m1 = id.Match(m.Value);
if (m1.Success) { expr.Add(m1.Value); continue; }
m1 = num.Match(m.Value);
if (m1.Success) { expr.Add(m1.Value); continue; }
m1 = skobki.Match(m.Value);
if (m1.Success)
{
if (m1.Value == "(") { stOper.Push(m1.Value); continue; }
var op = stOper.Pop().ToString();
while (op != "(")
{
expr.Add(op);
op = stOper.Pop().ToString();
}
continue;
}
m1 = opers.Match(m.Value);
if (m1.Success)
{
try
{
while (Array.IndexOf(operators, m1.Value) > Array.IndexOf(operators, stOper.Peek()))
{
if (stOper.Peek().ToString() == "(") break;
expr.Add(stOper.Pop().ToString());
}
}
catch (Exception)
{
// stack is empty
}
stOper.Push(m1.Value);
}
}
while (stOper.Count != 0)
{
expr.Add(stOper.Pop().ToString());
}
// Make the RPN expression string
// from the ArrayList expr.
var res = new StringBuilder();
foreach (var s in expr)
res.Append(s).Append(' ');
return res.ToString();
}
如何修改代码以使该方法public static string Translate(string input)
将简单的表达式(如 array_name[i,k*i-1])转换为 RPN 表达式?
请注意,该public static string Translate(string input)
方法仅适用于简单的算术表达式,但不适用于我上面提供的那个(if-else 语句)。