第一次:
一.表達式處理
題目要求表達式合法,而不合法的表達式顯然是不能進行后續操作的,因此第一步要做的就是把不合法的表達式排除在外。
我的想法是這樣的:
1. 把所有包含正確表達式不該有的字符的輸入屏蔽掉
2. 把所有包含非法數字的表達式屏蔽掉
3. 把所有含有類似“+++”、“+-+”、“^++”等的表達式屏蔽掉,為下一步的拆分做鋪墊
4. 當表達式差分成一個個項的時候,只要有一個項出現異常,整個串即為不合法
其中可能會出現一些細節問題,例如:
1. 判斷非法字符的方法:我采用了最土的方法,把合法字符全部刪除,如果還存在字符則顯然非法。
2. 不合法數字的正則表達式:"(.*)[-\\+\\^][-\\+]( )+(\\d)(.*)"和"(.*)(\\d)( )+(\\d)(.*)"。
3. 處理分隔符時的方法:因為我采取的分割口是“+”,所以每兩個項之間必須有一個加號,還要保證x^\\d中不能出現加號,因此要將將x^\\d中可能出現的加號刪除,將++換成+,--換成+,-+和-換成+-,這樣就可以保證所有拆分出來的項都是合法的。當然如果表達式開頭出現加號則在開頭加上“0”,結尾出現加號則屏蔽掉。
二.項的處理
將切分好的項進行標准化,化成"(.*)*x^(.*)"的形式,以便使用*x^進行切割,將兩邊的數字進行處理,為防止數據溢出采用biginteger,一旦出現異常,則表達式顯然不合法。將處理好的鍵值對存入hashmap中,通過冪次相等來合並同類項。
求導,更新hashmap中的數值等待輸出。
三.輸出處理
將每個鍵值對標准化成"\\d*x^\\d\\+"的形式,添加到同一個空字符串上,將系數或指數為0或1的項進行化簡,最后刪除最末尾的+即可輸出。
第二次:
一.表達式處理
和第一次基本相同,又略有差異。首先將不合法表達式粗略的排除在外。
具體操作如下:
1.排除空串(將所有‘\t’轉化成‘ ’)
2.將所有包含非合法字符(串)的表達式排除(合法字符包括^*+- 以及數字、(x)、sin、cos)
3.將所有含有類似“++++”、“+-+-”、“^++”、“*++”等的表達式屏蔽掉,為拆分做鋪墊
4.數字非法的正則表達式前多加入正負號,其他均與第一次相同
5.拆分好的項被稱為乘法項,作為下一步處理的輸入
二.乘法項的處理
將切分好的項再以*號分割,並將同類項合並,利用通式求導化簡存入哈希表,x的冪次作為key,新建triangle類用與化簡三角函數,最后輸出。其他均與第一次相同。
三.化簡處理
顯然輸出結果中會出現sinx^2+cosx^2等情況,我在作業中做了如下處理。
1. 合並同類項(以x為key)
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,而后直接判錯
可能我的代碼並不是真正的面向對象,(不過相信會慢慢好起來的)。