作为一个个人项目的一部分,计算平方矩阵的Jordan形式,事实证明,为了简化大量代码,我需要解析具有复数系数的多项式。
(相关代码在帖子底部)
我想解析的多项式具有以下形式:
系数可以是实数,虚数或复数。
如果系数是复数,则将用括号括起来。 如果这些括号是前导系数,则不会在它们前面加上+或- 。
如果系数是真实的,虚构的,或复杂的本名和\\或虚部的幅度1时, 1将不会出现,但只有标志。
括号前面只能有+ 。
变量x可能具有幂( >2 ),可能具有1的幂,然后它就象x一样出现,或者根本不出现。
不再有关于多项式的文本表示的规则,即幂不一定按升/降序排序。
格式正确的多项式的一些示例:
1
-1
-2.1x
3i
x^2-1
-x^3+2x+1
(5-5i)x^2-x-1
(-1+i)x-5
-ix^3-x^2+1
..和一些格式错误的:
1x (导致不必要的1 )
+(+1-2i)x (括号的+(+1-2i)x带有+ ,实数部分的+(+1-2i)x带有+ )
(5.1i)x^2 (因为是虚数,所以不需要括号)
-(i-1) (复数系数开头- )
在网上阅读了一些文章(SO,Java教程,Java API)之后,我很快得出结论,考虑到上述所有限制,正则表达式将是最简单的解析方法。 从形式上讲,可以执行此任务的正则表达式,因为我绘制了NFA,该NFA仅接受此类有效表达式。
我正在执行此TDD(通过JUnit 4),并且此测试失败:
assertEquals("Polynomial parsed incorrectly.", poly07, PolyParser.parse(exp07));
poly07看起来像这样: (5-5i)x^2-x-1 。
这是正在引发的异常:
java.lang.NumberFormatException: For input string: "5-5"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at PolyParser.parse(PolyParser.java:55)
at PolyParserTest.testParse(PolyParserTest.java:59)
我尝试调试,发现正则表达式捕获5-5i (后来5-5i了i )。 然后,它尝试使用参数字符串5-5调用Double.parseDouble ,这将导致异常。
在阅读完所有内容之后,我无法完全确定正则表达式中需要进行哪些调整才能使整个演出正常进行。 另外,正则表达式的排序不像上面提到的表示约束那样,因为我想在尝试将系数解析为实数之前先看看它是否复杂。 还遇到将实数(即带小数点)解析为整数的问题,因此正则表达式首先处理实数。
正则表达式:
public static final String POLYNOMIAL_REGEX =
"([+-])?" + // leading plus or minus
"(\\()?" + // parenthesis to denote the beginning of a complex number
"([+-])?(((\\d+.\\d+)|\\d+)i)?" + // component of coefficient, imaginary
"(((-)?\\d+.\\d+)|\\d+)?" + // component of coefficient, real
"(\\))?" + // parenthesis to denote the end of a complex number
"(x)?" + // variable
"(?:\\^(\\d+))?"; // power of the variable
我不会在这里发布所有相关代码,因为这会使事情变得混乱。 所有代码都在GitHub上 ,只需确保切换到分支PolyParser 。
相关代码在文件中:
PolyParser.java
Polynomial.java
Complex.java
测试单元位于文件PolyParserTest.java 。