實驗說明
數據結構實驗二 棧的實驗——棧的簡單應用
一、實驗目的
通過本實驗使學生了解棧的簡單應用,熟悉棧的特性及棧在順序存儲上的操作特點,深刻理解棧的基本操作與用棧解決應用問題的關系;特別訓練學生使用棧解決實際問題的能力,為今后用棧解決相關問題奠定基礎。
二、實驗內容
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)寫程序一定要先靜下心來讀題目,在寫程序之前把頂層給設計好,以便后續實現功能。其次把要最終實現的功能細分下來,把一個個小的功能完成了,最后拼接起來完成程序,也就是程序的模塊化。