PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 60 | 30 |
· Estimate | · 估計這個任務須要多少時間 | 60 | 30 |
Development | 開發 | 1680 | 2320 |
· Analysis | · 需求分析 (包括學習新技術) | 120 | 100 |
· Design Spec | · 生成設計文檔 | 30 | 30 |
· Design Review | · 設計複審 (和同事審覈設計文檔) | 30 | 20 |
· Coding Standard | · 代碼規範 (爲目前的開發制定合適的規範) | 30 | 30 |
· Design | · 具體設計 | 60 | 120 |
· Coding | · 具體編碼 | 1200 | 1680 |
· Code Review | · 代碼複審 | 30 | 40 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 180 | 300 |
Reporting | 報告 | 390 | 510 |
· Test Report | · 測試報告 | 180 | 200 |
· Size Measurement | · 計算工做量 | 30 | 10 |
· Postmortem & Process Improvement Plan | · 過後總結, 並提出過程改進計劃 | 180 | 300 |
合計 | 2130 | 2860 |
In computing and systems design a loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components. Subareas include the coupling of classes, interfaces, data, and services.[1] Loose coupling is the opposite of tight coupling.git
——引用自維基百科程序員
void InputHandler(int argc, char* argv[], bool &enable_loop, int &word_or_char, char &head, char &tail, string &Filename); void ReadFile(string FileName, vector<string> &words); void DFS_Length(Graph G, int v, vector<string> words, char tail);
之前作過相似的題,輸入的全部單詞可否所有首尾相連造成鏈。因爲單詞首尾相連有多種鏈接方式,故基本的數據結構爲圖。
建圖有兩種方式,一種是以單詞爲節點,若是單詞間正好能夠首尾鏈接,則添加一條邊,該邊即爲鏈接的字母。另外一種建圖方式是以字母爲節點,以單詞爲邊,出現一個單詞,即把首字母節點向尾字母節點添加一條邊,邊的值即爲該單詞。
對於這道題目而言,因爲單詞須要輸出,加之對第二種建圖方式掌握並不熟練,所以選擇的是第一種建圖方式。
模型確立後,問題就能夠簡化成「求圖中的最長鏈」,即最長路徑問題,顯然問題是多源最長路徑問題。github
數據結構爲圖,存儲方式爲鄰接矩陣,理由是能更契合floyd算法。
對於無環狀況,因爲爲多源最長路徑問題,聯想到最短路徑問題,能夠肯定爲floyd算法。
而對於有環狀況,因爲出現了正值環,floyd算法再也不適用。在找不到更有解決方法的狀況下,只能適用DFS深度優先搜索求解。算法
ReadFile: 讀取文件的模塊,將文件中的單詞提取進入容器vector中。
Graph: 圖的定義。
InputHandler:處理輸入的模塊,讀取命令行並處理參數。
FindLongestWordList: 計算模塊,內含計算接口。計算出單詞中的最長鏈。編程
首先須要判斷有無環,對於沒有-r參數的輸入來講,若是有環須要報錯。這裏也是用到DFS的染色算法。每一個點有三種狀態:未遍歷過,遍歷過,當前序列正在遍歷。若是一次DFS中一個點與正在遍歷中的點相連了,說明DFS回到了以前的點,即圖中有環。
另外一問題是因爲無環狀況最多可有10000個單詞,而floyd算法時間複雜度爲O(n^3),暴力的計算顯然是不行的。考慮到對於無環的狀況,有以下特性:對於單詞element和elephant,因爲無環,這兩個單詞最多隻有一個會出如今鏈中。(不然會出現element, t..., ..., ....e, elephant / element,這樣必定是有環的),而若是要知足字母最多,顯然這時候須要選擇elephant加入鏈中。所以咱們能夠對於全部首尾字母相同的單詞,保留首尾字母組合中,最長的一個單詞。這樣的操做以後,最多的單詞數目爲351,即便是時間複雜度O(n^3)的算法也能很快得出結果。另外能夠計算得,最長鏈的長度最大爲51。數組
——優缺點引用自維基百科數據結構
TEST_METHOD(TestMethod3) { // TODO: normal_test3 char* words[101] = { "element", "heaven", "table", "teach", "talk"}; char* answer[101]; for (int i = 0; i < 101; i++) { answer[i] = (char*)malloc(sizeof(char) * 601); } int l = gen_chain_word(words, 5, answer, 0, 0, true); Assert::AreEqual(l, 4); Assert::AreEqual("table", answer[0]); Assert::AreEqual("element", answer[1]); Assert::AreEqual("teach", answer[2]); Assert::AreEqual("heaven", answer[3]); for (int i = 0; i < 101; i++) { free(answer[i]); } }
TEST_METHOD(TestMethod6) { // TODO: normal_test6 char* words[101] = { "apple", "banane", "cane", "a", "papa", "erase" }; char* answer[101]; for (int i = 0; i < 101; i++) { answer[i] = (char*)malloc(sizeof(char) * 601); } int l = gen_chain_char(words, 6, answer, 'a', 'e', false); Assert::AreEqual(l, 3); Assert::AreEqual("a", answer[0]); Assert::AreEqual("apple", answer[1]); Assert::AreEqual("erase", answer[2]); for (int i = 0; i < 101; i++) { free(answer[i]); } }
TEST_METHOD(TestMethod2) { // 正確_2 int argc = 6; char* argv[101] = { "Wordlist.exe", "-r", "-h", "a", "-c", "test_1.txt" }; char head; char tail; bool enable_loop; int word_or_char = 0; string Filename; InputHandler(argc, argv, enable_loop, word_or_char, head, tail, Filename); Assert::AreEqual(enable_loop, true); Assert::AreEqual(word_or_char, 2); Assert::AreEqual(head, 'a'); Assert::AreEqual(tail, char(0)); Assert::AreEqual(Filename, (string)"test_1.txt"); }
單元測試覆蓋率截圖(因爲C++沒有找到直接測試單元測試覆蓋率的插件,這裏用的方法是將單元測試代碼移至main函數中用OpenCppCoverage插件獲得的覆蓋率,部分異常測試沒有放進來,因此覆蓋率沒有達到100%)app
TEST_METHOD(TestMethod3) { // 錯誤_1 int argc = 5; char* argv[101] = { "Wordlist.exe", "-r", "-r", "-c", "test_1.txt" }; char head; char tail; bool enable_loop; int word_or_char = 0; string Filename; try { InputHandler(argc, argv, enable_loop, word_or_char, head, tail, Filename); Assert::IsTrue(false); } catch (myexception1& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是‘-r’出現了兩次,錯誤的參數組合。函數
TEST_METHOD(TestMethod7) { // 錯誤_5 int argc = 6; char* argv[101] = { "Wordlist.exe", "-r", "-h", "1", "-c", "test_1.txt" }; char head; char tail; bool enable_loop; int word_or_char = 0; string Filename; try { InputHandler(argc, argv, enable_loop, word_or_char, head, tail, Filename); Assert::IsTrue(false); } catch (myexception2& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是‘-h’指定首字母爲‘1’,明顯是錯誤的。oop
TEST_METHOD(TestMethod9) { // 錯誤_7 int argc = 5; char* argv[101] = { "Wordlist.exe", "-b", "-r", "-c", "test_1.txt" }; char head; char tail; bool enable_loop; int word_or_char = 0; string Filename; try { InputHandler(argc, argv, enable_loop, word_or_char, head, tail, Filename); Assert::IsTrue(false); } catch (myexception3& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是輸入參數‘-b’顯然是不符合規定的。
TEST_METHOD(TestMethod2) { // 錯誤 vector <string> words; try { ReadFile("normal_test3.txt", words); // 不存在的文件 Assert::IsTrue(false); } catch (myexception4& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是測試了一個在此路徑下不存在的文件。
TEST_METHOD(TestMethod2) { // 錯誤 vector <string> words; try { ReadFile("long_word_test.txt", words); Assert::IsTrue(false); } catch (myexception4& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是文件中存在長度超過600的單詞。
TEST_METHOD(TestMethod2) { // 錯誤 vector <string> words; try { ReadFile("more_words_test.txt", words); Assert::IsTrue(false); } catch (myexception4& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是所測試文件中單詞數超過了10000。
TEST_METHOD(TestMethod10) { // wrong_test2 char* words[101] = { "alement", "oeaven", "tabla", "teaco", "talk" }; char* answer[101]; for (int i = 0; i < 101; i++) { answer[i] = (char*)malloc(sizeof(char) * 601); } try { int l = gen_chain_char(words, 5, answer, 0, 'n', false); Assert::IsTrue(false); } catch (myexception7& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是傳入單詞能夠造成環,且用戶沒有傳入參數‘-r’。
TEST_METHOD(TestMethod11) { // wrong_test3 char* words[101] = { "alement", "oeaven", "tabla", "teaco", "talk" }; char* answer[101]; for (int i = 0; i < 101; i++) { answer[i] = (char*)malloc(sizeof(char) * 601); } try { int l = gen_chain_word(words, 5, answer, 'b', 'n', true); Assert::IsTrue(false); } catch (myexception8& e) { Assert::IsTrue(true); } catch (...) { Assert::IsTrue(false); } }
這個單元測試是規定了首尾字母后,單詞鏈中沒有用戶所要求的單詞鏈。