数据结构 实验报告(二) 栈的应用
前言
学校的作业,如果看到了,不用怀疑,就是校友😀
实验说明
数据结构实验二 栈的实验——栈的简单应用
一、实验目的
通过本实验使学生了解栈的简单应用,熟悉栈的特性及栈在顺序存储上的操作特点,深刻理解栈的基本操作与用栈解决应用问题的关系;特别训练学生使用栈解决实际问题的能力,为今后用栈解决相关问题奠定基础。
二、实验内容
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)写程序一定要先静下心来读题目,在写程序之前把顶层给设计好,以便后续实现功能。其次把要最终实现的功能细分下来,把一个个小的功能完成了,最后拼接起来完成程序,也就是程序的模块化。