1. 程式人生 > 實用技巧 >資料結構 實驗報告(二) 棧的應用

資料結構 實驗報告(二) 棧的應用

實驗說明

資料結構實驗二 棧的實驗——棧的簡單應用

一、實驗目的

通過本實驗使學生了解棧的簡單應用,熟悉棧的特性及棧在順序儲存上的操作特點,深刻理解棧的基本操作與用棧解決應用問題的關係;特別訓練學生使用棧解決實際問題的能力,為今後用棧解決相關問題奠定基礎。

二、實驗內容

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)寫程式一定要先靜下心來讀題目,在寫程式之前把頂層給設計好,以便後續實現功能。其次把要最終實現的功能細分下來,把一個個小的功能完成了,最後拼接起來完成程式,也就是程式的模組化。