2019 OO第一單元總結(表達式求導)

来源:https://www.cnblogs.com/yifan-liu/archive/2019/03/27/10606851.html
-Advertisement-
Play Games

一. 基於度量的程式結構分析 1. 第一次作業 這次作業是我上手的第一個java程式,使用了4個類來實現功能。多項式採用兩個arraylist來存,繫數和冪指數一一對應。 四個類分別為 Poly類,代表表達式; PolyDiff類,代表求導運算; PolyParse類,封裝了格式檢查,encodin ...


一. 基於度量的程式結構分析

1. 第一次作業

  這次作業是我上手的第一個java程式,使用了4個類來實現功能。多項式採用兩個arraylist來存,繫數和冪指數一一對應。

1 private ArrayList<BigInteger> coefs;
2 private ArrayList<BigInteger> degrees;

  四個類分別為

  • Poly類,代表表達式;
  • PolyDiff類,代表求導運算;
  • PolyParse類,封裝了格式檢查,encoding(輸入的多項式轉為內部存儲形式),優化,decoing(內部存儲形式轉為輸出的多項式)方法;
  • PolyDiffTest類,入口類

  整個程式既有面向對象的味道(封裝),但不那麼純,也有面向過程的寫法。

類圖如下:

類複雜度分析如下:

       

優缺點分析:  

  這裡PolyParse類的代碼尤其多,在整個設計中,PolyParse類是主類,完成了大多數功能,其他類是輔助類。這樣的寫法犯了面向對象的一個大忌:類失衡。究其原因,還是受到了面向過程思想的影響。其次可以直接用Hashmap而不是arraylist來存表達式。

  對於第二次作業而言,本次作業的擴展性還行,給出了整個求導的框架。


 

 

2. 第二次作業

  本次作業最重要的變化是加入了三角函數。為了使用上次作業的架構,我只改變了表達式的存儲形式。對於求導,採用的方式還是和上次作業一樣,直接帶公式。關鍵是項的表示形式。

  以 x, sin(x), cos(x) 做為基函數,對於任何項 kxasin(x)bcos(x)都可以表示為 (k,(a,b,c))(k,(a,b,c)),

  採用複合函數求導公式 (uvw)' = (uvw)=uvw+uvw+uvw′ 得到的結果為3個項,具體形式可以拿公式直接得出來。

類圖如下:

類複雜度分析如下:

    

優缺點分析:  

  這裡優化的類裡面的代碼尤其多,為了保證每個方法的行數小於限制行數,只能強行將優化函數拆成3個不同功能的優化,但裡面有很多冗餘的代碼。

  對於第三次作業而言,本次作業不具任何的擴展性,這種求導的框架走到了盡頭。


 

 

3. 第三次作業

  本次作業加入了嵌套因數和表達式因數,由於前兩次作業不能擴展以及之前寫過編譯器的經驗,這一次我是推倒重來,從頭開始寫了小型編譯器。

  求導過程可看作是一個翻譯過程:源語言:原表達式,目標語言:求導後的表達式。指導書上對於item的要求看起來複雜,但拆成一個個小單元後,很容易就能寫出item的文法,之後採用遞歸下降分析法,一次掃描,同時完成了格式檢查和求導的工作。

  我d得這次作業最精彩的是我的求導都是形式求導,實質是字元串的拼接

  比如a=b*c 有了b和c本身以及b和c求導後的表達式b',c'的string形式,套公式(字元串拼接)就可以得到c'=b'c+bc'的string形式。整個過程非常簡單。不論是乘法,加法還是嵌套,都可以用這種方式解決。

類圖如下:

類複雜度分析如下:

          

優缺點分析:

  採用了編譯器的經典架構:Expr,Item,Factor,Lexer,Symbol,Pow,Sin,Cos類的劃分明確,職責清晰。類複雜度分析圖中標紅的地方是由於使用了大量的if,else或者switch,但這個也必須用,不知道有沒有更好的對於if,else的改寫方法。

  還是只用了封裝,繼承,多態,介面一個都沒用上。註意之後的重構部分會給出一些修改方法。


 

 

二. bug分析

第一次作業: 

  較為簡單,暫無bug發現

第二次作業:

  這次作業的bug出在了優化部分,可謂是畫蛇添足。

  測試用例:3*x + sin(x)^5*cos(x) - sin (x)^3*cos(x) - sin(x)*cos(x)^5 + sin(x)*cos(x)^3

  錯誤輸出:7*sin(x)^2*cos(x)^2-4+7*cos(x)^2  

  特征:向map中添加元素的時候,沒有先調用get()來得到原來的key之後再累加上去,而是直接調用put()方法覆蓋了原來的key。導致程式中如果有一個以上sinx^2+cosx^2=1或1-sinx^2=cosx^2或1-cosx^2=sinx^2的合併時出現錯誤。

  問題所在的類和方法:Optimization類的opt1,optimization1,optimization2方法。

  bug位置與設計結構之間的相關性:優化類的結構一開始每個方法寫的很長,超出了最大行數的限制,之後強行拆成了幾個方法,導致方法的功能有些混亂,在測試時沒有找到bug。

  分類樹角度分析程式在設計上的問題:分類樹是一種使用樹狀結構來構造測試用例的方法,避免了測試用例的冗餘。我在本次作業中構建的測試用例只針對了正確性,對於能夠優化的用例,我只構造了幾個,沒有完全覆蓋優化的函數。

第三次作業:

  暫無bug發現,為了防止錯誤出現,沒有做過多優化。


 

 

三. 測試方法

  雖然我們沒有互測,但自動測試可以顯著提高測試效率,很有必要實現對拍程式。

1. 構建測試用例

  對於第三次作業,情況較為複雜,採用隨機生成大量用例的方法易生成大量類似測試用例,不能保證全覆蓋。我依照指導書精心設計了30多個用例,保證了測試的全覆蓋。

2. 測試方法

  稍微修改java程式的Main方法,使其從文件讀表達式,將結果輸出到文件。使用python的sympy庫編寫對拍程式,符號求導,代入隨機數運算後比對,實現了正確格式用例的測試。對於Wrong Format的測試,直接看java程式是否輸出WF。


 

 

四. Applying Creational Pattern

  第三次作業依舊沒有使用繼承和介面,但每個類的形式都是一樣的。

 1 private String fun = "";
 2 private String diffFun = "";
 3 
 4 String getFun() {
 5     return fun;
 6 }
 7 
 8 String getDiff() {
 9     return diffFun;
10 }
11 
12 void analyse() {
13     ......  
14 }

  重構:

  新建一個父類對象Expression包含fun和diffFun變數成員,getFun()和getDiff()函數成員。由於每個子類的analyse()行為不一樣,無法使用父類的getFun()和getDiff()完成功能,因此直接將analyse定義為一個介面。每一個子類需要繼承父類Expression並且實現介面analyse。

  我的設計思路中也體現出Factory Pattern的思想。因為語法分析的結果實質是構建了一個語法樹,每一個父節點都會創建兩個子節點,並且調用子節點的getFun()和getDiff()函數,整個過程是一個遞歸過程,最終從樹的根節點上拿到結果。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 深層理解-棧平衡原理-底層是如何實現棧平衡的? 在iOS、android操作系統中,經常會遇到入棧出棧的操作。 那麼現在操作系統已經不需要我們去關心堆棧的操作。 比如:iOS中的ARC模式,android中的JVM都會幫我們自動釋放記憶體,自動保持堆棧平衡。但是對於開發者來說,還是很有必要掌握堆棧平衡 ...
  • 對於一個的坐擁1.4億多用戶,平均日活躍用戶量超過 3400 萬,人均日訪問時長 1 小時,月累計頁面訪問量達到 230 億的大廠來說(數據截止2018年 3 月),知乎的AI都到底應用在了哪些領域,這中間應用到了哪些技術和模型,又產生了哪些作用?今日第1期數智方法論將從內容生產、內容消費與分發、內... ...
  • 那個時候初入java這個大家庭,學習的方向很亂。畢業後,在公司磨練了一年,總想著是該交一份答卷了,可能成績不會很好,但求及格!那麼考試題目呢,我計劃搭建一個橫向可擴展的項目,可以在平臺自擴展各種子項目,包括 後臺許可權控制,日誌分析,秒殺,微信小程式,愛代客(www.idaike.com)項目等等,所 ...
  • OO第一單元作業總結 在第一單元作業中,我們只做了一件事情:求導,對多項式求導,對帶三角函數的表達式求導,對有括弧嵌套的表達式求導。作業難度依次遞增,讓我們熟悉面向對象編程方法,開始從面向過程向面向對象轉變。本文中,我將介紹我個人每一次作業的做法,以及三次作業的分析,互測時策略。 第一次作業 第一次 ...
  • 第一次OO博客作業 前言 面向對象課程已經經過了4周的時間。前三次作業全部是關於多項式求導的相關內容,內容由易到難,同時我也開始逐漸深入感受學習面向對象的各項特征,逐漸將自己的編程風格從C向真正的面向對象語言轉換。同時我還接觸了DEBUG和互測屋這樣嶄新的學習方式,在閱讀別人代碼的過程中不斷增強自己 ...
  • 一、由於項目需要進行手機看板展示設計及開發展示效果圖如下: 上圖為概況(點擊相應模塊進入詳情頁面) 上圖為運營統計(一些統計類圖標狀圖折線圖等......) 車輛分佈狀況(展示在地圖上分佈) 上圖為點擊一輛車的軌跡和運行情況 此產品唯一亮點在於完全可以把利用HTML5和echarts開發大數據大屏展 ...
  • 本文是BUAA OO課程Unit1在課程講授、三次作業完成、自測和互測時發現的問題,以及傾聽別人的思路分享所引起個人的一些思考的總結性博客。本文第二部分介紹三次作業的設計思路,主要以類圖的形式展現,並有簡單的優劣分析;第三部分為程式代碼複雜度的分析(二、三兩部分為基於度量的對自己程式結構的分析);第... ...
  • 一、前言 經過一個月來的學習,我從對面向對象一無所知到逐漸入門,圍繞著“多項式求導”,對面向對象的特性進行了探索。 我對面向對象印象最深的兩句話就是“萬物皆對象”和“高內聚、低耦合”,這三次作業也是儘量貫徹了這兩句話。 我們的作業從第一次的僅含冪函數的求導,到第二次包含正餘弦函數,再到最後函數可以嵌 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...