C语言编程练习day17

本文介绍了栈在解决后缀表达式求解和括号匹配问题中的应用。通过链栈实现,对于后缀表达式,遇到数字入栈,遇到运算符则计算并压入结果;对于括号匹配,遇到左括号进栈,右括号时匹配栈顶左括号,最后检查栈是否为空,确保所有括号都已匹配。
摘要由CSDN通过智能技术生成

1、栈的应用_后缀表达式求解
通过之前链栈的相关API来辅助完成。需要在新项目中导入LinkStack.h和LinkStack.c两个文件(在C语言编程练习day13中有).
思路:遍历后缀表达式。1、遇到数字,直接进栈。2、遇到符号,从栈中弹出两个数,第一个数作为右操作数,第二个作为左操作数,然后根据符号进行运算并将运算的结果压入栈。遍历结束后,栈中剩下的唯一数字,就是计算结果。
输入:831-5 *+
输出:18
优化目标:无
完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "LinkStack.h"

//数据结构体
typedef struct MYDATA {
	LinkNode node;
	int val;
}MyData;

/*
* 判断是否为数字
* @c:待判断的字符
*/
int isNumber(char c) {
	return c >= '0' && c <= '9';
}

/*
* 遇到运算符的计算函数
* @leftNum:左操作数
* @rightNum:右操作数
* @c:操作符
*/
int Calculate(int leftNum, int rightNum, char c) {
	int result = 0;
	switch (c)
	{
	case '+':
		result = leftNum + rightNum;
		break;
	case '-':
		result = leftNum - rightNum;
		break;
	case '*':
		result = leftNum * rightNum;
		break;
	case '/':
		result = leftNum / rightNum;
		break;
	default:
		break;
	}
	return result;
}


int main() {
	//后缀表达式
	char* str = "831-5*+";
	char* p = str;

	//初始化栈
	LinkStack* stack = Init_LinkStack();

	while (*p != '\0') {
		if (isNumber(*p)) {
			//如果扫描到操作数,直接进栈
			MyData* data = (MyData*)malloc(sizeof(MyData));
			data->val = *p - '0';
			//入栈
			Push_LinkStack(stack, (LinkNode*)data);
		}else {//扫描到操作符
			//从栈中弹出第一个数,作为右操作数
			MyData* right = (MyData*)Top_LinkStack(stack);
			int rightNum = right->val;
			Pop_LinkStack(stack);
			free(right);

			//从栈中弹出第一个数,作为左操作数
			MyData* left = (MyData*)Top_LinkStack(stack);
			int leftNum = left->val;
			Pop_LinkStack(stack);
			free(left);

			//计算结果,并压入栈
			int ret = Calculate(leftNum, rightNum, *p);
			MyData* result = (MyData*)malloc(sizeof(MyData));
			result->val = ret;
			Push_LinkStack(stack, (LinkNode*)result);
		}

		p++;
	}

	//打印栈中的最后一个数
	if (Size_LinkStack(stack) == 1) {
		MyData* num = (MyData*)Top_LinkStack(stack);
		printf("%d", num->val);
		Pop_LinkStack(stack);
		free(num);
	}
	//释放栈
	FreeSpace_LinkStack(stack);

	return 0;
}

2、栈的应用_括号匹配
思路:扫描字符串,如果是左括号,则直接入栈。如果是右括号,如果栈不空,从栈顶弹出一个括号,匹配成功;如果栈空,则该右括号没有可匹配的左括号,则指出其位置。当扫描完字符串时,若栈不空,则栈中剩余括号都没有可匹配的右括号。
输入:(1-2))+(((6+)*3+((8+8)
输出
在这里插入图片描述
优化目标:无

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "LinkStack.h"

typedef struct MYCHAR {
	LinkNode node;
	char* pAddress;
	int index;
}MyChar;

/*
*判断是否是左括号
*@c:待判断的字符
*/
int isLeft(char c) {
	return c == '(';
}

/*
*判断是否是右括号
*@c:待判断的字符
*/
int isRight(char c) {
	return c == ')';
}

/*
*打印函数,打印不匹配的位置,并由"A"指向
*@pos:不匹配括号的位置
*@str:扫描的字符串
*/
void Print(int pos, char* str) {
	printf("%s\n", str);
	for (int i = 0; i < pos; i++) {
		printf(" ");
	}
	printf("%c", 'A');
	printf("\n");
}

int main() {
	
	char* str = "(1-2))+(((6+)*3+((8+8)";
	char* p = str;
	int index = 0;

	//初始化栈
	LinkStack* stack = Init_LinkStack();

	while (*p != '\0') {
		if (isLeft(*p)) {
			//如果是左括号,直接进栈
			MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
			mychar->pAddress = p;
			Push_LinkStack(stack, (LinkNode*)mychar);
			mychar->index = index;
		}
		//右括号
		if (isRight(*p)) {
			//如果栈不空,则出栈
			if (Size_LinkStack(stack) > 0) {
				Pop_LinkStack(stack);
			}else {
				//该右括号没有匹配的左括号,打印输出其位置
				printf("没有匹配的右括号\n");
				
				Print(index, str);
			}
		}

		index++;
		p++;
	}

	//如果栈不空,则有没有匹配的左括号
	while (Size_LinkStack(stack) > 0) {
		printf("没有匹配的左括号\n");
		MyChar* mychar = (MyChar*)Top_LinkStack(stack);
		Print(mychar->index, str);
		Pop_LinkStack(stack);
		free(mychar);
	}

	//释放栈
	FreeSpace_LinkStack(stack);
	return 0;
}

总结:今天写了栈应用中的括号匹配和后缀表达式求值。明天学写查找相关知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别偷我的猪_09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值