此计算器解析错误的解决方法 [英] Workaround for this calculator parsing error

查看:149
本文介绍了此计算器解析错误的解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文:

我在自己制作的计算器中输入了表达式3.24 * 10^10 + 1. 我的计算器解决此问题的方法是-首先查找模式number_a^number_b,使用Double.parseDouble()方法将2个数字解析为双精度,然后执行Math.pow(number_a, number_b)并将结果替换为表达式.

I entered a expression 3.24 * 10^10 + 1 into a calculator that I made. My calculator's approach to solve this is - it first looks for pattern number_a^number_b, parses the 2 numbers into double using Double.parseDouble() method, then performs Math.pow(number_a, number_b) and replaces the expression with the result.

然后,计算器类似地查找模式number_a * number_b并将其解析.到目前为止,我们的表达式变为3.24E10 + 1.现在是棘手的部分.当我对此计算器进行编程时,考虑到计算器应该找到模式number_a + number_b并对其进行解析,所以我这样做了.我的计算器确实做到了这一点,并以意外但合理的方式返回结果-3.24E11.0.

The calculator, then, similarly looks for pattern number_a * number_b and parses it. So far our expression becomes 3.24E10 + 1. Now comes the tricky part. When I programmed this calculator I did it under consideration that calculator should find the pattern number_a + number_b and parse it. My calculator indeed does this and returns the result as, unexpectedly but justifiably - 3.24E11.0.

我正在寻找一种解决方法,以使我的计算器足够智能以处理此类表达式.

I am looking for workaround to make my calculator smart enough to take care of such expressions.

重要信息-正则表达式示例= ([\\d\\.]+)\\*([\\d\\.]+)

Important information - Regex example = ([\\d\\.]+)\\*([\\d\\.]+)

代码示例-

// here 'expression' is a StringBuilder type
// only a (modified) snippet of actual code.

Matcher m = Pattern.compile ("([\\d\\.]+)\\^([\\d\\.]+)")
                           .matcher (expression.toString());
while (m.find()) {
     Double d1 = Double.parseDouble(m.group(1));
     Double d2 = Double.parseDouble(m.group(2));
     Double d3 = Math.pow(d1, d2);
     expression.replace(m.start(), m.end(), Double.toString(d3));
     m.reset(expression);
}

PS :许多人似乎基于我提出问题的方式,认为我的计算器是一次失败的尝试,因为正则表达式不会使我走得太远.当然,我同意这是正确的,并且可能存在更好的算法.我只想澄清一下:-

PS : Many people seem to think, based on how I presented the question, that my calculator is a failed attempt as regex won't take me too far. Ofcourse, I agree that is true and there may exist far better algorithms. I just want to make clear that :-

1)正则表达式仅用于解析直接形式的表达式.我不会对所有内容都使用正则表达式.嵌套括号使用递归解决.正则表达式仅在所有处理工作都已完成时才发挥作用,剩下的只是简单的计算.

1) Regex is only used for parsing expressions in direct form. I don't use regex for everything. Nested brackets are solved using recursion. Regex only comes to play at the last step when all the processing work has been done and what remains is only simple calculation.

2)我的计算器工作正常.它可以并且确实很好地解决了嵌套表达式.证明-2^3*2/4+1 --> 5.0sin(cos(1.57) + tan(cos(1.57)) + 1.57) --> 0.9999996829318346((3(2log(10))+1)+1)exp(0) --> 8.0

2) My calculator works fine. It can and does solve nested expressions gracefully. Proof - 2^3*2/4+1 --> 5.0, sin(cos(1.57) + tan(cos(1.57)) + 1.57) --> 0.9999996829318346, ((3(2log(10))+1)+1)exp(0) --> 8.0

3)不要使用太多的拐杖".如果您认为我已经编写了数千行代码来获取所需的功能. 200行,仅此而已.而且我无意转储我的应用程序(已接近完成).

3) Does not use too many 'crutches'. If you are of an opinion that I have written thousands of line of code to obtain the desired functionality. No. 200 lines and that's it. And I have no intention of dumping my application (which is near completion).

推荐答案

根据您的评论,通过更改此正则表达式:

According to your comment, by changing the regex from this:

([\\d\\.]+)\\*([\\d\\.]+)

要起作用:

(\\d+(\\.\\d+)?(e\\d+)?)\\^(\\d+(\\.\\d+)?(e\\d+)?)

要说明我已更改的内容:以前,您可以输入以下格式的数字:

To explain what I've changed: Before, you were allowed to enter numbers in the format:

  1. 1
  2. .5
  3. .......
  4. .3.76
  5. 依此类推
  1. 1
  2. .5
  3. .......
  4. .3.76
  5. and so on

要克服此问题:我添加了一个可选的小数位((\\.\\d+)?),该位允许整数,但也允许小数.

To overcome this: I added an optional decimal place ((\\.\\d+)?), which allows integers, but also decimals.

还通过在两边添加可选的科学符号((e\\d+)?),允许数字被写入:

Also by adding an optional scientific notation ( (e\\d+)?) on both sides, allows the numbers to be written:

  1. 作为整数(2 ^ 5)
  2. 为小数(2.3 ^ 5.7)
  3. 科学的(2.345e2 ^ 5e10)
  1. As integers (2 ^ 5)
  2. As decimals (2.3 ^ 5.7)
  3. And as scientific (2.345e2 ^ 5e10)

您当然可以混合所有变体.

You can of course mix all variants up.

但是请记住您问题下方的评论.正则表达式对于一些小东西可能有用,但是当方程式越大时,它会变得笨拙,缓慢且混乱.

But keep in mind the comments below your question. Regex is for small bits maybe useful, but it can get pretty clumpy, slow and messed up, the bigger the equations get.

如果您想支持负数,则可以在基数和指数前面添加可选的连字符:

Also if you want to support negative numbers, you can add optional hyphens in front of the bases and the exponents:

(-?\\d+(\\.\\d+)?(e-?\\d+)?)\\^(-?\\d+(\\.\\d+)?(e-?\\d+)?)

这篇关于此计算器解析错误的解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆