求導計算器


第一次:

一.表達式處理

題目要求表達式合法,而不合法的表達式顯然是不能進行后續操作的,因此第一步要做的就是把不合法的表達式排除在外。

我的想法是這樣的:

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.排除空串(將所有‘\t’轉化成‘ ’)

 

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,而后直接判錯

可能我的代碼並不是真正的面向對象,(不過相信會慢慢好起來的)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM