栈的应用—

就近匹配

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
示例:

  1. 建立一个 LinkStack.h 的头文件
    受限线性表中的”栈的链式存储“中的头文件所示。
  2. 建立一个 LinkStack.c 的源文件
    受限线性表中的"栈的链式存储"的源文件所示
  3. 建立一个 07栈的应用 源文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"


typedef struct MYCHAR
{
	LinkNode node;
	char* pAddres;
	int index;

}MyChar;
int IsLeft(char c)
{
	return c=='(';
}
int IsRight(char c)
{
	return c==')';
}

MyChar* CreatMyChar(char* p,int index)
{
	MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
	mychar->pAddres = p;
	mychar->index = index;
	return mychar;
}

//标记函数,当匹配失败的时候将出错位置的括号标记出来
void ShowError(char* str, int pos)
{
	printf("%s\n", str);
	for(int i = 0; i < pos; i++)
	{
		printf(" ");
	}
	printf("A");
}


int main()
{
	//创建栈容器
	LinkStack* lstack = Init_LinkStack();
	char* str = "1+2+6(stf)dfsflp((sdfs)";
	char* p = str;
	int index = 0;
	while (*p != '\0')
	{
		//如果是左括号则入栈
		if (IsLeft(*p))
		{
			Push_LinkStack(lstack,CreatMyChar(p,index));
		}
		//如果是右括号,从栈顶弹出元素,判断是不是左括号
		if (IsRight(*p))
		{
			if (Size_LinkStack(lstack)> 0)
			{
				MyChar* mc = Top_LinkStack(lstack);
				if (IsLeft(*(mc->pAddres)))
				{
					Pop_LinkStack(lstack);
					free(mc);
				}
			}
			else 
			{
				printf("右括号没有匹配的左括号");
				ShowError(str, index);
				break;
			}
		}
		p++;
		index++;
	}

	while (Size_LinkStack(lstack)> 0)
	{
		MyChar* myc = Top_LinkStack(lstack);
		printf("左括号没有匹配的右括号:\n");
		ShowError(str, myc->index);
		Pop_LinkStack(lstack);
		free(myc);
	}

	return 0;
}

结果:

左括号没有匹配的右括号:
1+2+6(stf)dfsflp((sdfs)

中缀表达式和后缀表达式

在这里插入图片描述
在这里插入图片描述

示例:

  1. 建立一个 LinkStack.h 的头文件
    受限线性表中的”栈的链式存储“中的头文件所示。
  2. 建立一个 LinkStack.c 的源文件
    受限线性表中的"栈的链式存储"的源文件所示
  3. 建立一个 08中缀转后缀.c 源文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"

int IsNumber(char c) {
	return c >= '0' && c <= '9';
}
//数字操作
void NumberOperate(char* p) {
	printf("%c", *p);
}

//判断是不是左括号
int IsLeft(char c) {
	return c == '(';
}

typedef struct MYCHAR {
	LinkNode node;
	char* p;
}MyChar;

//创建MyChar
MyChar* CreateMyChar(char* p) {
	MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
	mychar->p = p;
	return mychar;
}

//左括号操作
void LeftOperate(LinkStack* stack, char* p) {
	Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
}
//判断是不是右括号
int IsRight(char c) {
	return c == ')';
}
//右括号操作
void RightOperate(LinkStack* stack) {
	//先判断栈中有无元素
	while (Size_LinkStack(stack) > 0) {
		MyChar* mychar = (MyChar*)Top_LinkStack(stack);
		//如果匹配到左括号
		if (IsLeft(*(mychar->p))) {
			Pop_LinkStack(stack);
			break;
		}
		//先输出再弹出
		printf("%c", *(mychar->p));
		Pop_LinkStack(stack);
		//释放内存
		free(mychar);
	}
}
//判断是不是运算符号
int IsOperator(char c) {
	return c == '+' || c == '-' || c == '*' || c == '/';
}
//返回运算符号优先级
int GetPriority(char c) {
	if (c == '*' || c == '/') {
		return 2;
	}
	if (c == '+' || c == '-') {
		return 1;
	}
	return 0;
}
//运算符号的操作
void OperatorOperate(LinkStack* stack, char* p) {
	//先取出栈顶符号
	MyChar* mychar = (MyChar*)Top_LinkStack(stack);

	if (mychar == NULL) {
		Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
		return;
	}
	//如果栈项优先级低于当前字符的优先级直接入栈
	if (GetPriority(*(mychar->p)) < GetPriority(*p)) {
		Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
		return;
	}
	//如果栈顶符号优先级不低
	else {
		while (Size_LinkStack(stack) > 0) {
			MyChar* mychar2 = (MyChar*)Top_LinkStack(stack);
			//如果优先级低当前符号入栈
			if (GetPriority(*(mychar2->p)) < GetPriority(*p)) {
				Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
				break;
			}
			//先输出,再弹出
			printf("%c", *(mychar2->p));
			Pop_LinkStack(stack);
			//释放内存
			free(mychar2);
		}
	}
}

int main(void) {

	char* str = "8+(3-1)*5";
	char* p = str;

	//创建栈
	LinkStack* stack = Init_LinkStack();

	while (*p != '\0') {
		//如果是数字
		if (IsNumber(*p)) {
			NumberOperate(p);
		}
		//如果是左括号,直接进栈
		if (IsLeft(*p)) {
			LeftOperate(stack, p);
		}
		//如果是右括号
		if (IsRight(*p)) {
			RightOperate(stack);
		}
		//如果是运算符号
		if (IsOperator(*p)) {
			OperatorOperate(stack, p);
		}
		p++;
	}

	while (Size_LinkStack(stack) > 0) {
		MyChar* mychar = (MyChar*)Top_LinkStack(stack);
		printf("%c", *(mychar->p));
		Pop_LinkStack(stack);
		free(mychar);
	}
	printf("\n");
	system("pause");

	return 0;
}

结果:

831-5*+

基于后缀表达式计算

在这里插入图片描述
在这里插入图片描述
示例:

  1. 建立一个 LinkStack.h 的头文件
    受限线性表中的”栈的链式存储“中的头文件所示。
  2. 建立一个 LinkStack.c 的源文件
    受限线性表中的"栈的链式存储"的源文件所示
  3. 建立 09根据后缀表达式求解
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"

int IsNumber2(char c) {
	return c >= '0' && c <= '9';
}
typedef struct MYNUM {
	LinkNode node;
	int val;
}MyNum;

int Caculate(int left, int right, char c) {
	int ret = 0;
	switch (c) {
	case '+':
		ret = left + right;
		break;
	case '-':
		ret = left - right;
		break;
	case '*':
		ret = left * right;
		break;
	case '/':
		ret = left / right;
		break;
	default:
		break;
	}
	return ret;
}
int main(void) {
	//后缀表达式
	char* str = "831-5*+";
	char* p = str;
	//创建栈
	LinkStack* stack = Init_LinkStack();
	while (*p != '\0') {
		//如果是数字直接入栈
		if (IsNumber2(*p)) {
			MyNum* num = (MyNum*)malloc(sizeof(MyNum));
			num->val = *p - '0';
			Push_LinkStack(stack, (LinkNode*)num);
		}
		else {
			//先从栈中弹出右操作数
			MyNum* right = (MyNum*)Top_LinkStack(stack);
			int rightNum = right->val;
			Pop_LinkStack(stack);
			free(right);
			//取出左操作数
			MyNum* left = (MyNum*)Top_LinkStack(stack);
			int leftNum = left->val;
			Pop_LinkStack(stack);
			free(left);

			int ret = Caculate(leftNum, rightNum, *p);
			//结果入栈
			MyNum* num = (MyNum*)malloc(sizeof(MyNum));
			num->val = ret;
			Push_LinkStack(stack, (LinkNode*)num);
		}
		p++;
	}

	if (Size_LinkStack(stack) == 1) {
		MyNum* num = (MyNum*)Top_LinkStack(stack);
		printf("运算结果是:%d\n", num->val);
		Pop_LinkStack(stack);
		free(num);
	}
	//释放栈
	FreeSpace_LinkStack(stack);

	printf("\n");
	system("pause");
	return 0;
}

结果:

运算结果是:18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值