zoukankan      html  css  js  c++  java
  • 求导计算器

    第一次:

    一.表达式处理

    题目要求表达式合法,而不合法的表达式显然是不能进行后续操作的,因此第一步要做的就是把不合法的表达式排除在外。

    我的想法是这样的:

    1. 把所有包含正确表达式不该有的字符的输入屏蔽掉

    2. 把所有包含非法数字的表达式屏蔽掉

    3. 把所有含有类似+++”、“+-+”、“^++”等的表达式屏蔽掉,为下一步的拆分做铺垫

    4. 当表达式差分成一个个项的时候,只要有一个项出现异常,整个串即为不合法

    其中可能会出现一些细节问题,例如:

    1. 判断非法字符的方法:我采用了最土的方法,把合法字符全部删除,如果还存在字符则显然非法。

    2. 不合法数字的正则表达式:"(.*)[-\+\^][-\+]( )+(\d)(.*)""(.*)(\d)( )+(\d)(.*)"

    3. 处理分隔符时的方法:因为我采取的分割口是+”,所以每两个项之间必须有一个加号,还要保证x^\d中不能出现加号,因此要将将x^\d中可能出现的加号删除,将++换成+--换成+-+-换成+-,这样就可以保证所有拆分出来的项都是合法的。当然如果表达式开头出现加号则在开头加上“0”,结尾出现加号则屏蔽掉。

    二.项的处理

    将切分好的项进行标准化,化成"(.*)*x^(.*)"的形式,以便使用*x^进行切割,将两边的数字进行处理,为防止数据溢出采用biginteger,一旦出现异常,则表达式显然不合法。将处理好的键值对存入hashmap中,通过幂次相等来合并同类项。

    求导,更新hashmap中的数值等待输出。

    三.输出处理

    将每个键值对标准化成"\d*x^\d\+"的形式,添加到同一个空字符串上,将系数或指数为01的项进行化简,最后删除最末尾的+即可输出。

    第二次:

    一.表达式处理

    和第一次基本相同,又略有差异。首先将不合法表达式粗略的排除在外。

    具体操作如下:

    1.排除空串(将所有‘ ’转化成‘ ’)

    2.将所有包含非合法字符(串)的表达式排除(合法字符包括^*+- 以及数字、(x)、sincos

    3.将所有含有类似“++++”、“+-+-”、“^++”、“*++”等的表达式屏蔽掉,为拆分做铺垫

    4.数字非法的正则表达式前多加入正负号,其他均与第一次相同

    5.拆分好的项被称为乘法项,作为下一步处理的输入

    二.乘法项的处理

    将切分好的项再以*号分割,并将同类项合并,利用通式求导化简存入哈希表,x的幂次作为key,新建triangle类用与化简三角函数,最后输出。其他均与第一次相同。

    三.化简处理

    显然输出结果中会出现sinx^2+cosx^2等情况,我在作业中做了如下处理。

    1. 合并同类项(以xkey

    2. 当出现asinx^(m+2)cosx^(n)+bsinx^(n)cosx^(n+2),ab>0时,可以进行化简提取通式将sin2+cos2化简成1,并降低幂次和系数

    3. 当出现类似asinx^(m)cosx^(n)-asinx^(m)cosx^(n+2)时,可以将两项划为一项

    4. 当出现1-sinx^2时合并成一项。最后按照第一次输出。

    第三次:

    一.表达式处理

    1.判断是否有输入,如果有,则扫描一行字符,判断是否存在非法字符。

    2.判断是否存在不合法数字,即:9  9+++  9^+  9*+  9等(同时避免了++++^++*++等的出现。

    3.判断是否存在不合法加减号,并替换成++-两种状态。

    4.为满足以加号分割的需求,将所有非连接表达式的+号替换成&

    5.将切分好的各项存入term

    二.项的处理

    1.将每个项用*号分割,并存入factor,同时判断拆分出来的表达式的类型,使用term递归。

    2.在处理过程中,严格把控每一种情况,一旦出现非法表达式或项,立刻抛出异常。

    三.Term

    1.Term分为三类,

    (1).x类:经过求导之后,直接输出导函数

    (2).sin类:经过求导之后,输出原函数减一次幂乘上脱掉外层括号后的导函数

    (3).cos类:经过求导之后,输出原函数减一次幂乘上脱掉外层括号后的导函数

    2.脱括号:当整个表达式不包含在括号外的*+时,可以脱掉一层括号,当不能再脱括号时转化成一个Factor

    3.求完导数后的结果套上一层括号,保存为一个字符串

    4.Term类数组中的所有导数相加即得到结果

    四.Factor

    1.Factor类用*号切割,把每一个切开的项用链式求导法则求导。

    2.求完导数后的结果套上一层括号,保存为一个字符串

    五.输出处理

    本次输出我完全没有处理,还是求稳好一点吧。

     关于互测:

    三次作业我并没有采用对拍等方式进行互测找bug,而是通过查看正则表达式的方法,寻求bug突破点,同时也发现了许多值得注意的地方:

    1.多数同学采用的是Pattern和Matcher类来处理正则,而我直接用(.*)和matches方法来处理。

    2.部分同学使用超长正则一次性匹配,在bug检查时简直无懈可击,但是可能会出现TLE等不可预知的情况

     我的bug:

    第一次出现在正则表达式中的+号和*号失误,导致空格的判断出现问题

    第二次出现在化简时符号省略出错,导致输出变得诡异

    第三次出现在参数带入错误,导致删括号的函数直接删掉了所有外围括号,将许多例如(1)+(1)等的测试点处理成了1)+(1,而后直接判错

    可能我的代码并不是真正的面向对象,(不过相信会慢慢好起来的)。

  • 相关阅读:
    产品设计理应遵循哪些原则?
    产品经理必读的九步法
    exec
    Class convert
    Connecting method
    ASP.NET读写操作
    Encrypt Decrypt
    EventHandler, EventArgs
    Convert using code
    Dictionary List
  • 原文地址:https://www.cnblogs.com/xiaokunshou/p/10587884.html
Copyright © 2011-2022 走看看