我正在尝试在Java中制作一个函数绘图程序,它涉及获取用户输入的要绘制的函数,解析它并将其绘制出来。例如,用户可能输入x ^ 2-y ^ 2,cos(x + y),log(x)-sqrt(y)等。该程序利用中缀二元操作符(+,-等)和一元操作符(cos,sqrt等)。
简而言之,为了评估一元操作符,我必须确保给定的表达式遵循单个一元操作符的格式。例如,cos(x),sqrt(x + y)和log(exp(y)-x)都符合这种格式,因为它们是带有某些表达式作为操作数的一元操作符;但是,像sin(x)* cos(y)和1 + log(x)这样的字符串不符合此格式。为了检查,我制作了一个正则表达式来匹配这种格式:
(这只是一个正则表达式,用于检查给定的字符串是否为预定义的一元操作符名称)
我会给你一个解释。这个正则表达式是在寻找一元运算符的名称。之后,它查找左括号。接着,它寻找一些不是括号的字符序列,然后再寻找以左括号开始、右括号结束的序列。后者防止类似"sin(x)+cos(y)"的字符串匹配。
简而言之,为了评估一元操作符,我必须确保给定的表达式遵循单个一元操作符的格式。例如,cos(x),sqrt(x + y)和log(exp(y)-x)都符合这种格式,因为它们是带有某些表达式作为操作数的一元操作符;但是,像sin(x)* cos(y)和1 + log(x)这样的字符串不符合此格式。为了检查,我制作了一个正则表达式来匹配这种格式:
String unaryName = "((productlog)|(zeta)|(log)|(sqrt)|(cos)|(sin)|(tan)|(sec)|(csc)|(csc)|(abs)|(arccos)|(arcsin)|(arctan)|(arcsec)|(arccsc)|(arccot)|(gamma)|(exp))";
(这只是一个正则表达式,用于检查给定的字符串是否为预定义的一元操作符名称)
String unaryOperation = unaryName + "\\(([^\\(\\)]*(\\(.*\\))*[^\\(\\)]*)+\\)"
我会给你一个解释。这个正则表达式是在寻找一元运算符的名称。之后,它查找左括号。接着,它寻找一些不是括号的字符序列,然后再寻找以左括号开始、右括号结束的序列。后者防止类似"sin(x)+cos(y)"的字符串匹配。
据我观察,无论何时使用这个正则表达式都会得到期望的结果。但是,在使用它时会遇到一个问题。考虑以下情况:
String s = "cos(3) + sin(4)";
System.out.println(s.matches(unaryOperation));
显然,如果正则表达式起作用,那么它应该返回false,而它确实是这样的。 这个例子也是一样的:
String s = "cos(3.000) + sin(4)";
System.out.println(s.matches(unaryOperation));
从模式上来说,实际上没有发生什么变化。但是,将零逐个添加到数字3后,匹配似乎需要指数级的时间才能评估。对于我来说,12个零大约需要13秒钟。由于我的程序将在图表上绘制许多点,每次绘制时都必须计算成千上万个表达式,因此这是一个致命缺陷。
我已经找到了避免使用该正则表达式的方法,我的程序工作得非常好,但我仍然想知道:为什么这个正则表达式在处理大输入时需要如此长的时间,并且是否有任何方法可以更改正则表达式以解决此问题?