练习题----顺序栈算法

这篇具有很好参考价值的文章主要介绍了练习题----顺序栈算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目:

​ 输入一个包括 '(' 和 ')' 的字符串string ,判断字符串是否有效。要求设计算法实现检查字符串是否有效,有效的字符串需满足以下条件:

A. 左括号必须用相同类型的右括号闭合。

B. 左括号必须以正确的顺序闭合。

C. 每个右括号都有一个对应的相同类型的左括号。

题目分析:

​ 该题需要满足三个条件,左括号类型,数量,顺序都得一致,所以选择使用顺序栈结构来实现。

​ 主要思路为遍历两次字符串。第一次遍历时,将遇到的左括号依次存入顺序栈中;第二次遍历时,每当遇到右括号时,便执行弹栈操作,并将弹栈出的元素与右括号类型进行对比。若类型一致,则继续遍历;若类型不一致,则将此时的栈顶元素下标加一且终止遍历,代表该字符串无效。

​ 最后通过判断顺序栈中栈顶元素下标是否为-1,即顺序栈中是否还有元素,来判定字符串是否有效。

原理图示:

练习题----顺序栈算法

代码实现:

/*********************************************************************
*
*	name	 :	SeqStack_JudgString
*	function : 根据用户输入的字符串中的括号个数与匹配度进行判断字符串的
				正确性
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回新的栈地址
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
void SeqStack_JudgString( DataType_t *str)
{
	//创建顺序栈
	SeqStack_t *SequenceStack = SeqStack_Create(sizeof(str));

	//计算得到的字符串长度
	int n = strlen(str);
	//遍历得到的字符串,将字符串中各中类型的左括号按先后顺序放入顺序栈中
	for (int i = 0; i < n;i++)
	{
		if(str[i] == '(')
			SeqStack_Push(SequenceStack, str[i]);
		else if(str[i] == '[')
			SeqStack_Push(SequenceStack, str[i]);
		else if(str[i] == '{')
			SeqStack_Push(SequenceStack, str[i]);
	}



	//再次对字符串遍历,找到对应的右括号,并且判断类型是否相符合
	for (int i = 0; i < n; i++)
	{
		if(str[i] == ')')
		{
			DataType_t temp = SeqStack_Pop(SequenceStack);
			if('('== temp) //弹栈出的元素是相同类型的左括号时,继续遍历
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
		else if(str[i] == ']')
		{
			DataType_t temp1 = SeqStack_Pop(SequenceStack);
			if('[' == temp1)
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
		else if(str[i] == '}')
		{
			DataType_t temp2 = SeqStack_Pop(SequenceStack);

			if('{'== temp2)
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
	}



	//判断匹配后的左右括号数量是否一致
	if(SequenceStack->Top == -1)
		printf("The string is valid!\n");
	else
		printf("The string is invalid!\n");


	return;
}

代码整体展示:

/*******************************************************************
 *
 *	file name:	SequenceStack_demo.c
 *	author	 :  790557054@qq.com
 *	date	 :  2024/04/25
 *	function :  该案例是利用顺序栈实现判断一个字符串是否有效,即通过判断
				括号数是否能够正确匹配得出结论
 * 	note	 :  None
 *
 *	CopyRight (c)  2023-2024   790557054@qq.com   All Right Reseverd
 *
 * *****************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

//指的是顺序栈中的元素的数据类型,用户可以根据需要进行修改
typedef char  DataType_t;

//构造记录顺序栈SequenceStack各项参数(栈底地址+栈容量+栈顶元素的下标)的结构体
typedef struct SequenceStack
{
	DataType_t * Bottom;		//记录栈底地址
	unsigned int Size;			//记录栈容量
	int			 Top;      		//记录栈顶元素的下标	

}SeqStack_t;
/*********************************************************************
*
*	name	 :	SeqStack_Create
*	function :  创建一个空的顺序栈,并为记录顺序栈信息的结构体
				申请堆内存,并进行初始化即可!
*	argument :  
*				@size  :栈的容量大小
*				
*	retval	 :  调用成功返回顺序栈的地址
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
//创建顺序表并对顺序栈进行初始化
SeqStack_t * SeqStack_Create(unsigned int size)
{
	//1.利用calloc为顺序栈的管理结构体申请一块堆内存
	SeqStack_t *Manager = (SeqStack_t *)calloc(1,sizeof(SeqStack_t));

	if(NULL == Manager)
	{
		perror("calloc memory for manager is failed");
		exit(-1); //程序异常终止
	}

	//2.利用calloc为所有元素申请堆内存
	Manager->Bottom = (DataType_t *)calloc(size,sizeof(DataType_t));

	if (NULL == Manager->Bottom)
	{
		perror("calloc memory for Stack is failed");
		free(Manager);
		exit(-1); //程序异常终止
	}

	//3.对管理顺序栈的结构体进行初始化(元素容量 + 最后元素下标)
	Manager->Size = size;	//对顺序栈中的容量进行初始化
	Manager->Top = -1;		//由于顺序栈为空,则栈顶元素的下标初值为-1
	
	return Manager;
}
/*********************************************************************
*
*	name	 :	SeqStack_IsFull
*	function : 判断顺序栈是否已满
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回bool型,满了则返回true,没满返回false
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
bool SeqStack_IsFull(SeqStack_t *Manager)
{
	return (Manager->Top + 1 == Manager->Size) ? true : false;
}
/*********************************************************************
*
*	name	 :	SeqStack_Push
*	function : 根据栈的特性,把新元素从栈顶入栈,也就是从数组的尾部进行元素插入
*	argument :  
*				@Manager  :顺序栈的地址
				@Date  	  :要入栈的数据
*				
*	retval	 :  调用成功返回bool型,满了则返回true,没满返回false
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
//入栈
bool SeqStack_Push(SeqStack_t *Manager, DataType_t Data)
{
	//1.判断顺序栈是否已满
	if ( SeqStack_IsFull(Manager) )
	{
		printf("SeqStack Full is Full!\n");
		return false;
	}

	//2.如果顺序栈有空闲空间,则把新元素添加到顺序栈的栈顶
	Manager->Bottom[++Manager->Top] = Data;

	return true;
}

/*********************************************************************
*
*	name	 :	SeqStack_IsEmpty
*	function : 	判断顺序栈是否为空
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回bool型,空了则返回true,没空返回false
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
bool SeqStack_IsEmpty(SeqStack_t *Manager)
{
	return (-1 == Manager->Top) ? true : false;
}
/*********************************************************************
*
*	name	 :	SeqStack_Pop
*	function : 根据栈的特性,把元素从栈顶出栈,也就是把元素从数组的尾部把元素删除
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回新的栈地址
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
//出栈
DataType_t SeqStack_Pop(SeqStack_t *Manager)
{
	DataType_t temp = 0;  //用于存储出栈元素的值

	//1.判断顺序栈是否为空
	if ( SeqStack_IsEmpty(Manager) )
	{
		// printf("SeqStack is Empty!\n");
		return -1;
	}
	
	//2.由于删除了一个元素,则需要让顺序栈的栈顶元素下标-1
	temp = Manager->Bottom[Manager->Top--];

	return temp;
}

/*********************************************************************
*
*	name	 :	SeqStack_JudgString
*	function : 根据用户输入的字符串中的括号个数与匹配度进行判断字符串的
				正确性
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回新的栈地址
*	author	 :  790557054@qq.com
*	date	 :  2024/04/25
* 	note	 :  none
* 	
* *****************************************************************/
void SeqStack_JudgString( DataType_t *str)
{
	//创建顺序栈
	SeqStack_t *SequenceStack = SeqStack_Create(sizeof(str));

	//计算得到的字符串长度
	int n = strlen(str);
	//遍历得到的字符串,将字符串中各中类型的左括号按先后顺序放入顺序栈中
	for (int i = 0; i < n;i++)
	{
		if(str[i] == '(')
			SeqStack_Push(SequenceStack, str[i]);
		else if(str[i] == '[')
			SeqStack_Push(SequenceStack, str[i]);
		else if(str[i] == '{')
			SeqStack_Push(SequenceStack, str[i]);
	}



	//再次对字符串遍历,找到对应的右括号,并且判断类型是否相符合
	for (int i = 0; i < n; i++)
	{
		if(str[i] == ')')
		{
			DataType_t temp = SeqStack_Pop(SequenceStack);
			if('('== temp) //弹栈出的元素是相同类型的左括号时,继续遍历
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
		else if(str[i] == ']')
		{
			DataType_t temp1 = SeqStack_Pop(SequenceStack);
			if('[' == temp1)
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
		else if(str[i] == '}')
		{
			DataType_t temp2 = SeqStack_Pop(SequenceStack);

			if('{'== temp2)
				continue;
			else
			{
				SequenceStack->Top++;
				break;
			}
		}
	}



	//判断匹配后的左右括号数量是否一致
	if(SequenceStack->Top == -1)
		printf("The string is valid!\n");
	else
		printf("The string is invalid!\n");


	return;
}

int main(int argc, char const *argv[])
{

	while(1)
	{
	//定义一个字符串指针变量 用于存储用户输入的字符串
	DataType_t  str[200];
	printf("Please input a string containing parentheses :\n ");
	scanf("%s", str);
	SeqStack_JudgString( str);
	}



	return 0;
}

结果验证:

练习题----顺序栈算法

待优化问题:

  • 如果右括号在最前面时,应该判断是无效,但是目前算法无法判断,例如:)(1+2 该算法会判断有效 是错误判断

优化思路:

​ 将判断’(‘和 ’)‘的判断放进一个循环里面判断,这样比两次遍历的时间复杂度更低,需要吸取教训,优化自身解题思路,思考更多样的情况。

图示:

练习题----顺序栈算法文章来源地址https://www.toymoban.com/news/detail-858648.html

到了这里,关于练习题----顺序栈算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】顺序表详解(附leetcode练习题)

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:数据结构 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺

    2023年04月27日
    浏览(47)
  • 10 SQL进阶 -- 综合练习题 -- 10道经典SQL题目,配套数据与解答

    点击下方链接直接下载 创建数据表脚本:http://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/SQL/create_table.sql 执行建表语句 执行成功 查看创建的表 点击下方链接直接下载 插入数据脚本:https://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/SQL/data.zip 大家下载好脚本后,先在MySQL环境中运

    2024年04月27日
    浏览(39)
  • JAVA面向对象练习题,课后编程题。题目为:公司员工分为5类,每类员工都有相应的封装类。

    某公司的员工分为5类,每类员工都有相应的封装类,这5个类的信息如下 (1)Employee:这是所有员工的父类。 ①属性:员工的姓名、员工的生日月份。 )方法:getSalary(int month)根据参数月份确定工资。如果该月员工过生日,则公司会额外发放100元。 (2)SalariedEmployee:Employee 

    2024年02月05日
    浏览(49)
  • 【UML】-- 顺序图练习题含答案(自动售货机、学生选课、提款机、购买地铁票、洗衣机工作)

    根据下面的叙述,绘制一幅关于顾客从自动售货机中购买物品的顺序图。 顾客( User )先向自动售货机的前端( Front )投币; 售货机的识别器( Register )识别钱币; 售货机前端( Front )根据 Register 的识别结果产生商品列表; 顾客选择商品; 前端控制的出货器( Dispense

    2023年04月18日
    浏览(117)
  • <算法学习>动态规划练习题

    本篇文章为初学动态规划时的练习题。参考优质博客学习后根据伪代码描述完成代码。记录一下用于以后复习。 给定一个有n行数字组成的数字三角形. 试设计一个算法, 计算出从三角形的顶至底的一条路径, 使该路径经过的数字和最大. 算法设计: 对于给定的n行数字组成的三角

    2024年01月17日
    浏览(47)
  • Matlab:遗传算法,模拟退火算法练习题

    1、遗传算法 (1) 遗传算法 是一种基于自然选择原理和自然遗传机 制的搜索(寻优)算法,它是模拟自然界中的生命进化机制,在人工系统中实现特定目 标的优化。遗传算法的实质是通过群体搜索技术,根据适者生存的原则逐代进化,最终 得到最优解或准最优解。它必须

    2024年01月21日
    浏览(45)
  • 拓扑排序 (算法思想+图解+模板+练习题)

    有向无环图一定是拓扑序列,有向有环图一定不是拓扑序列。 无向图没有拓扑序列。 首先我们先来解释一下什么是有向无环图: 有向就是我们两个结点之间的边是有方向的,无环的意思就是整个序列中没有几个结点通过边形成一个圆环。 下图就是一个有向无环图,它也一定

    2024年02月03日
    浏览(64)
  • 【算法设计与分析】动态规划-练习题

    输入一个整数数组 S[n] ,计算其最长递增子序列的长度,及其最长递增子序列。 定义 k ( 1 ≤ k ≤ n ) k (1 ≤ k ≤ n) k ( 1 ≤ k ≤ n ) ,L[k]表示以 S[k] 结尾的递增子序列的最大长度。子问题即为 L[k]。 对于每一个k,我们都遍历前面0~k-1的所有的数,找出最大的L[i],且 S [ k ] L [

    2024年02月03日
    浏览(57)
  • 数据结构与算法系列之习题练习

    💗 💗 博客:小怡同学 💗 💗 个人简介:编程小萌新 💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞 括号匹配问题。 用队列实现栈。 用栈实现队列。 设计循环队列。 有效的括号 //用栈来实现 //左括号进栈 右括号出栈并销毁如果不匹配则return //设置两个队列,入栈

    2024年02月11日
    浏览(46)
  • 数据结构与算法--图(概念+练习题+解析)

    有向图 在有向图中有以下几点结论: 1.所有顶点的度数之和等于边数的二倍。 2.所有顶点的入度之和等于出度之和。 3.n个顶点的有向完全图有n(n-1)条边。 4.n个顶点的强连通图至少有n条边。 无向图 在无向图中有以下几点结论: 1.所有顶点的度数之和等于边数的二倍。 2.n个顶

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包