資料結構 實驗報告(二) 棧的應用
實驗說明
資料結構實驗二 棧的實驗——棧的簡單應用
一、實驗目的
通過本實驗使學生了解棧的簡單應用,熟悉棧的特性及棧在順序儲存上的操作特點,深刻理解棧的基本操作與用棧解決應用問題的關係;特別訓練學生使用棧解決實際問題的能力,為今後用棧解決相關問題奠定基礎。
二、實驗內容
1.程式設計實現對給定的一組括號序列判斷其是否匹配正確。要求:
(1)它必須成對出現,如“(”“)”是一對,“[”與“]”是一對;
(2)出現時有嚴格的左右關係;
(3)可以以巢狀的方式同時出現多組多括號,但必須是包含式巢狀,不允許交叉式巢狀。比如“( )”、“[([][])]”這樣是正確的,“[(])”或“([()))”或 “(()]”是不正確的。
(4)將處理的括號擴充套件為針對“()”“[]”“{}”三類。
2.程式設計實現一個簡單的行編輯功能:使用者可以輸入一行內容,並可進行簡易編輯。要求:
(1)遇到輸入部分內容有誤時操作退格符“#”表示前一位無效;
(2)“@”表示之前的內容均無效。
實驗報告
1.實現功能描述
程式設計實現對給定的一組括號序列判斷其是否匹配正確,將處理的括號擴充套件為針對“()”“[]”“{}”三類,遇到輸入部分內容有誤時操作退格符“#”表示前一位無效;“@”表示之前的內容均無效。
2.方案比較與選擇
(1)可以使用棧和佇列來實現。因為棧的功能足以完成題目要求,所以初步打算使用棧來實現。
(2)因為編寫一個標準的棧比較繁瑣,而且本題中也沒有用到所有棧的標準操作,所以通過模擬棧來完成本題。
(3)可以使用陣列或連結串列來模擬棧。因為括號匹配只有3對,所需空間不是很大,又因為特殊操作#、@可以在陣列中通過-1和賦0值實現,因此選擇了陣列法來模擬棧。
3.設計演算法描述
(1)定義3個變數,分別用於記錄()、[]、{}的出現次數。遇到左符號時變數++,遇到右符號時--,變數為0時表示空棧。當讀到#時,再往前讀一個字元,如果是()、[]、{}中的一種,則對其進行反向運算,即遇到右符號時++,遇到左符號時--。
(2)進行模組劃分,給出功能組成框圖。形式如下:
(3)基本功能模組:
①讀取使用者輸入的內容
②檢查匹配情況
③輸出結果
(4)用流程圖描述關鍵演算法:
4.演算法實現(即完整源程式,帶註解)
點選檢視詳細內容
#include <stdio.h> #include <string.h> int input(char* temp); void check(char* temp, int i, int* parentheses, int* brackets, int* braces, int flag); void print(int parentheses, int brackets, int braces); void printresult(int parentheses, int brackets, int braces); int main(void) { //parentheses小括號,brackets中括號,braces大括號 //flag的作用:當讀到一個#時,對上一個讀到的括號數量減1 //temp用於儲存輸入的內容,tmp用於儲存第i個字元 int parentheses = 0, brackets = 0, braces = 0; int i, length, flag; char temp[1000]; printf("此程式的功能是:檢測括號是否匹配。\n請輸入檢測的內容,一行中僅有.時結束輸入:\n"); length = input(temp); //一個個字元去檢查括號匹配情況,到陣列末尾結束 for (i = 0, flag = 1; i < length; i++) { check(temp, i, &parentheses, &brackets, &braces, flag); } print(parentheses, brackets, braces); } //讀取使用者輸入的內容,返回內容長度 int input(char* temp) { int i; char tmp; for (i = 0; ; i++) { temp[i] = getchar(); if (temp[i] == '.') { tmp = getchar(); if (tmp == '\n') { temp[++i] = '\0'; break; } else { temp[++i] = tmp; } } } return strlen(temp); } //檢查當前字元是否為特定符號()[]{} void check(char* temp, int i, int* parentheses, int* brackets, int* braces, int flag) { switch (temp[i]) { case '#': if (i != 0) { flag = -1; check(temp, i - 1, parentheses, brackets, braces, flag); flag = 1; } break; case '@': *parentheses = 0; *brackets = 0; *braces = 0; break; case '(': if (*parentheses >= 0 || flag == -1) { *parentheses += flag; } break; case ')': *parentheses -= flag; break; case '[': if (*brackets >= 0 || flag == -1) { *brackets += flag; } break; case ']': *brackets -= flag; break; case '{': if (*braces >= 0 || flag == -1) { *braces += flag; } break; case '}': *braces -= flag; break; default: break; } } //輸出結果 void print(int parentheses, int brackets, int braces) { if (parentheses != 0 || brackets != 0 || braces != 0) { printf("NO\n"); } else { printf("YES\n"); } printresult(parentheses, brackets, braces); } //輸出結果 void printresult(int parentheses, int brackets, int braces) { if (parentheses != 0) { if (parentheses > 0) { printf("(-?"); } else { printf("?-)"); } } else if (brackets != 0) { if (brackets > 0) { printf("[-?"); } else { printf("?-]"); } } else if (braces != 0) { if (braces > 0) { printf("{-?"); } else { printf("?-}"); } } }
5.實驗結果測試與分析
(1)資料測試程式截圖
(2)對結果進行分析:
①能正確判斷符號是否配對
②能正確輸出未配對的符號
③能正確的處理特殊符號#
④能正確處理特殊符號@
6.思考及學習心得
(1)描述實驗過程中對此部分知識的認識:
(2)特別描述在學習方法上的收穫及體會;
(3)針對前面的思考題內容在此回答。
1)模擬了棧的執行,更進一步理解和掌握棧的的使用。
2)這次的實驗,鞏固了我的程式設計模組化的思想。模組化降低了程式的耦合性,提高了程式的內聚性;降低了程式複雜度,使程式設計、除錯和維護等操作簡單化。模組化使得程式設計更加簡單和直觀,從而提高了程式的易讀性和可維護性,而且還可以把程式中經常用到的一些計算或操作編寫成通用函式,以供隨時呼叫。
3)寫程式一定要先靜下心來讀題目,在寫程式之前把頂層給設計好,以便後續實現功能。其次把要最終實現的功能細分下來,把一個個小的功能完成了,最後拼接起來完成程式,也就是程式的模組化。