我想用c#从数学表达式中提取变量。我写了这段代码,它的工作正常:
List<string> Variables = new List<string>();
string temp = string.Empty;
Console.WriteLine("Please enter ur expression");
string Expression = Console.ReadLine().Trim();
int Index;
for (Index = 0; Index <= Expression.Length - 1; Index++)
{
if (char.IsLetter(Expression[Index]))
{
temp = temp + Expression[Index];
}
else
{
if (temp.Length > 0)
{
Variables.Add(temp);
temp = string.Empty;
}
}
}
if (temp.Length > 0)
{
Variables.Add(temp);
}
foreach (string item in Variables)
{
Console.WriteLine(item);
}
Console.ReadKey();
我必须从表达式中检测SIN和COS,因此我将从变量中删除SIN和COS。
提取后我想用输入中的值替换变量,我将计算表达式结果。
答案 0 :(得分:3)
尝试绘制检测表达式的自动机。 在那之后,实现自动机的最简单方法是使用嵌套if..else的switch..case。 我认为这比以现在的方式解析字符串要容易得多。
编辑 -
这是一个非常简单的例子,仅仅是为了演示。假设我想以var1 + var2的形式检测表达式,自动机将如下所示: Image
Implementaion看起来像这样:
done = false;
state = start;
while(!done)
{
switch(state)
{
case start:
if(expression[i] > 'a' && expression[i] < 'z')
state = start;
else if(expression[i] == '+')
{
// seen first operand and waitng for second
// so we switch state
state = add;
}
break;
case add:
if(expression[i] > 'a' && expression[i] < 'z')
state = add;
else
done = true;
break;
}
}
就像我说这很简单,你的自动机会更复杂,有更多的状态和转换。我也没有在这里包含动作,但是你可以在读完第二个操作数之后进行实际添加,这是在完成= true之后;
答案 1 :(得分:1)
我喜欢使用Shunting-yard算法: http://en.wikipedia.org/wiki/Shunting-yard_algorithm 它使eval变得容易。
答案 2 :(得分:1)
如果你想自己解决问题,你的方法似乎很好,但它没有评估它,在这种情况下我更喜欢使用先前写的解析器,如NCalc
,而不是创建风团,但如果这是一个家庭作业,你只想找到变量,你的方式可以通过例如做temp += Expression[Index];
来优化,也可以使用Experssion.Split(...
在这种情况下更好地工作。如果你想自己解析它,你可以使用关闭码算法。