在我的一个项目中,我想添加一个功能,例如用户可以在公式中提供
sin (x + pi)/2 + 1
Run Code Online (Sandbox Code Playgroud)
我在我的Java应用程序中使用它
/**
* The formula provided by the user
*/
private String formula; // = "sin (x + pi)/2 + 1"
/*
* Evaluates the formula and computes the result by using the
* given value for x
*/
public double calc(double x) {
Formula f = new Formula(formula);
f.setVar("x", x);
return f.calc();
// or something similar
}
Run Code Online (Sandbox Code Playgroud)
我如何评估数学表达式?
我挑战你写一个数学表达式评估器,它尊重PEMDAS(操作顺序:括号,取幂,乘法,除法,加法,减法)而不使用正则表达式,一个预先存在的"Eval()" - 类似函数,一个解析库等
我在SO(这里)看到了一个预先存在的评估者挑战,但那个特别需要从左到右的评估.
样本输入和输出:
"-1^(-3*4/-6)" -> "1"
"-2^(2^(4-1))" -> "256"
"2*6/4^2*4/3" -> "1"
Run Code Online (Sandbox Code Playgroud)
我在C#中编写了一个评估器,但是我想看看它与那些选择语言的智能程序员相比有多糟糕.
澄清:
让我们使这个函数接受一个字符串参数并返回一个字符串结果.
至于为什么没有正则表达式,那就是平衡竞争环境.我认为"最紧凑的正则表达式"应该有一个单独的挑战.
使用StrToFloat()是可以接受的.通过"解析库",我的意思是排除诸如通用语法解析器之类的东西,也用于平衡游戏场.
支持浮动.
支持paretheses,取幂和四个算术运算符.
赋予乘法和除法优先权.
赋予加法和减法相同的优先权.
为简单起见,您可以假设所有输入都是格式良好的.
我不喜欢你的函数是否接受".1"或"1e3"之类的东西作为有效数字,但是接受它们会获得布朗尼积分.;)
对于除零情况,您可能会返回"NaN"(假设您希望实现错误处理).
对于你所有的编译器大师,我想编写一个递归下降解析器,我想用代码来做.没有从其他语法生成词法分析器和解析器并且不告诉我阅读龙书,我最终会到达那里.
我想进入关于为一个合理的简单语言实现词法分析器和解析器的细节,比如说CSS.我想这样做.
这可能最终会成为一系列问题,但现在我开始使用词法分析器了.可以在此处找到CSS的标记规则.
我发现自己编写了这样的代码(希望你可以从这个片段推断出其余部分):
public CssToken ReadNext()
{
int val;
while ((val = _reader.Read()) != -1)
{
var c = (char)val;
switch (_stack.Top)
{
case ParserState.Init:
if (c == ' ')
{
continue; // ignore
}
else if (c == '.')
{
_stack.Transition(ParserState.SubIdent, ParserState.Init);
}
break;
case ParserState.SubIdent:
if (c == '-')
{
_token.Append(c);
}
_stack.Transition(ParserState.SubNMBegin);
break;
Run Code Online (Sandbox Code Playgroud)
这个叫什么?我离合理的东西有多远了?我试图在效率和易于使用方面平衡一些公平的东西,使用堆栈来实现某种状态机工作得很好,但我不确定如何继续这样做.
我所拥有的是一个输入流,我可以从中一次读取1个字符.我现在不做任何看法,我只是阅读角色,然后根据当前状态尝试做一些事情.
我真的很想进入编写可重用代码片段的思维模式.此Transition方法目前是这样做的,它将弹出堆栈的当前状态,然后以相反的顺序推送参数.这样,当我写Transition(ParserState.SubIdent, ParserState.Init)它时,它将"调用"一个子程序SubIdent,当完成后,它将返回Init状态.
解析器将以大致相同的方式实现,目前,在这样的单个大方法中,所有内容都允许我在找到令牌时轻松返回令牌,但它也迫使我将所有内容保存在一个单一的大方法中.有没有一种很好的方法将这些标记化规则拆分成单独的方法?
我被赋予了将一种语言"翻译"成另一种语言的工作.对于使用正则表达式的简单逐行方法,源代码太灵活(复杂).我在哪里可以了解有关词法分析和解析器的更多信息?
我有以下BoolExpr课程:
class BoolExpr
{
public enum BOP { LEAF, AND, OR, NOT };
//
// inner state
//
private BOP _op;
private BoolExpr _left;
private BoolExpr _right;
private String _lit;
//
// private constructor
//
private BoolExpr(BOP op, BoolExpr left, BoolExpr right)
{
_op = op;
_left = left;
_right = right;
_lit = null;
}
private BoolExpr(String literal)
{
_op = BOP.LEAF;
_left = null;
_right = null;
_lit = literal;
}
//
// accessor
//
public …Run Code Online (Sandbox Code Playgroud)