Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用正则表达式解析复系数多项式_Java_Regex_Parsing_Polynomials - Fatal编程技术网

Java 用正则表达式解析复系数多项式

Java 用正则表达式解析复系数多项式,java,regex,parsing,polynomials,Java,Regex,Parsing,Polynomials,作为计算方阵Jordan标准形个人项目的一部分,我需要解析复系数多项式,以简化大量代码 (职位底部的相关代码) 我想分析的多项式的形式如下: 系数可以是实系数、虚系数或复系数 如果系数是复杂的,它将用括号括起来。如果这些括号是前导系数,则它们前面不会有+或- 如果系数是实数、虚数或复数,其实部和/或虚部分量的大小为1,则1不会出现,而只会出现符号 括号前只能加+ 变量x可能有一个幂(>2),可能有一个1的幂,然后它会像x一样出现,或者根本不会出现 关于多项式的文本表示没有更多的规则,即幂不一定按

作为计算方阵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
      (括号有一个前导
      +
      ,实组件有一个前导
      +
    • (5.1i)x^2
      (因为系数是虚构的,所以不需要括号)
    • -(i-1)
      (复系数有前导
      -
    在网上阅读了一些内容(Java教程、JavaAPI)之后,我很快得出结论,考虑到上面提到的所有限制,正则表达式将是最简单的解析方法。 在形式方面,这个任务的regex是可能的,因为我绘制了NFA,只接受这样有效的表达式

    我正在执行此TDD(通过JUnit 4),但此测试失败:

    assertEquals(“多项式解析不正确”,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
    (后来去掉了
    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
    
    我不打算在这里发布所有相关的代码,因为它会把东西弄得乱七八糟。所有代码都已打开,只需确保切换到分支
    PolyParser

    相关代码在以下文件中:

  • PolyParser.java
  • polymonent.java
  • Complex.java

  • 测试单元位于文件
    PolyParserTest.java

    中,正则表达式基本上无法解析表达式,因为它们无法跟踪嵌套(例如,括号)。这是一个大多数人都不知道的教训,他们通过艰难的方式发现了这一点

    但是,表达式很容易解析,使用自顶向下的解析。请参阅我关于如何执行此操作的答案:此答案涵盖了如何进行解析,并链接到另一个关于如何构建AST来表示表达式的答案


    第一步:写一个语法,表示你的表达式将允许什么。你的问题中有一个特别的描述,但语法会迫使你准确地写出什么是合法的,什么是不合法的。使用这种语法,您可以非常轻松地编写上面建议的递归下降解析器。

    正则表达式几乎从来都不是解析问题的正确解决方案。我的建议是:不要。使用上下文无关的解析器,如果您想要一个简单的解析器,请查看。或者你可以全力以赴,使用像Antlr这样的东西。或者,你可以尝试一下,这一切都是开箱即用的,你甚至可以直接计算多项式。首先你要弄清楚你需要做什么。然后你选择必要的工具来做这件事。在这种情况下,您首先选择了工具。。。这是错误的假设,假设用户输入了正确格式的表达式,我们就放弃了防御性编程。这样,就没有嵌套的括号。我使用正则表达式及其捕获组作为解析器。当我手头上有一个几乎可以按我所希望的方式工作的正则表达式时,从零开始实现解析器似乎需要进行大量的研究和工作,只是缺少一些微调。你的想法?你的用户会在输入公式时出错。不管你喜欢与否,他们都会使用括号,你需要一个健壮的解析器。