首页 > 编程语言 >练习题----顺序栈算法

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

时间:2024-04-26 09:35:06浏览次数:28  
标签:练习题 SequenceStack SeqStack Manager ---- 括号 算法 顺序 str

题目:

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

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

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

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

题目分析:

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

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

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

原理图示:

image

代码实现:

/*********************************************************************
*
*	name	 :	SeqStack_JudgString
*	function : 根据用户输入的字符串中的括号个数与匹配度进行判断字符串的
				正确性
*	argument :  
*				@Manager  :顺序栈的地址
*				
*	retval	 :  调用成功返回新的栈地址
*	author	 :  [email protected]
*	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	 :  [email protected]
 *	date	 :  2024/04/25
 *	function :  该案例是利用顺序栈实现判断一个字符串是否有效,即通过判断
				括号数是否能够正确匹配得出结论
 * 	note	 :  None
 *
 *	CopyRight (c)  2023-2024   [email protected]   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	 :  [email protected]
*	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	 :  [email protected]
*	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	 :  [email protected]
*	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	 :  [email protected]
*	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	 :  [email protected]
*	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	 :  [email protected]
*	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;
}

结果验证:

image

标签:练习题,SequenceStack,SeqStack,Manager,----,括号,算法,顺序,str
From: https://www.cnblogs.com/fly-home/p/18159247

相关文章

  • Elasticsearch - Text字段排序
    插入数据DELETE/websitePUT/website{"mappings":{"properties":{"title":{"type":"text"}}}}PUT/website/_doc/1{"title":"firstclass"}PU......
  • Sping-依赖注入
    6、依赖注入6.1构造器注入(参考第三节)6.2Set注入依赖注入:set注入依赖注入依赖:bean对象的创建依赖于容器注入:bean对象中的所有属性由容器注入编写实体类//实体类一packagepojo;publicclassAddress{privateStringaddress;publicAddress(){......
  • 不得不说,在很多业务中,这种模式用得真的很香
    故事“不能在写ifelse来拓展当前系统了,现在已经有三个支付场景了......”工位上,小猫看着电脑,挠着头。就在刚刚,小猫接到了一个新需求,需要和客户公司打通资产,形成资产联动。说白了就是需要定制化对接客户公司的支付资产体系。除了这次接到的之外。前面其实已经对接了三家了。由于......
  • 不只有 Spring,这四款 Java 基础开发框架同样值得关注! 审核中
    Java开发不只有Spring,今天给大家推荐几个同样优秀的Java基础开发框架,为日常项目开发提供更多的选择。答应我,请不要再叫我Spring小子了,​好吗?项目概览:Guice:轻量级依赖注入框架Javalin:轻量级Java和KotlinWeb框架Quarkus:云原生时代高性能Java框架Vert.x:构建响应......
  • E. Chain Reaction
    https://codeforces.com/contest/1954/problem/E题意:n个数,可以对每个数释放闪电,闪电从释放的位置一直传到左右边界或者传到某个小于等于0的数终止,并且每个数都会减去闪电值k。问最少多少次释放闪电后可以让所有的数小于等于0。思路:从左往右考虑,假设第一个数的权值为1,如果当前数>......
  • 微雪 esp32c3 深度睡眠和 gpio 唤醒
    当项目由电源适配器供电时,我们一般不会太关心功耗。但是,如果要使用电池为项目供电,则需要精打细算。esp32深度睡眠在深度睡眠模式下,CPU、大多数RAM和所有数字外围设备都可以关闭。从深度睡眠中出来后,芯片通过复位重新启动,并从一开始就开始执行程序。系统无法自动进入深度睡眠......
  • 不谈虚的,平台即产品真的有那么好吗?
    随着信息技术的高速发展,我们每隔一段时间就能看到一个热门术语在各大平台被分析和讨论。当我们上搜索引擎搜索相关词条,就会找到大量与该技术优势、亮点相关的文章。特别是“平台即产品”(PaaP)策略,其在实际应用中的利用价值和效用性成为近期关注的焦点。 虽然构建数字平台以促进......
  • .NET Aspire 预览版 6 发布
    .NETAspire预览版6引入了一系列重大更新,主要包括API的重大更改、安全性和可靠性的提升、新的资源和组件、应用程序主机的更新、测试支持、模板更新、组件更新、Azure配置包的更新以及Azure开发者CLI对多个端点的支持。这些更新旨在提高.NETAspire的性能和用户体验,同......
  • js逆向实战之喜马拉雅Xm-Sign参数解密
    url:https://www.ximalaya.com/channel/11/分析过程抓包,关注有页面数据回显的数据包。该url的请求头中有个加密的参数,找到该参数的加密过程。由于该参数名比较不常见,可以直接全局搜索这个参数名。只有一处,打断点。切换页码,触发断点。非常直接,xm-sign是由d.getS......
  • Linux 登录后提示修改密码 怎么设置不提醒
    在Linux系统中,如果你登录后立即被提示修改密码,这通常是因为密码过期或者账户的密码有相关的策略限制。要设置不再提示,你可以修改密码的过期策略或修改账户的密码策略。以下是如何修改密码策略的步骤:以root用户登录或使用sudo。查看密码策略:根据需要修改密码策略。例如,要取消密......