就近匹配
示例:
- 建立一个 LinkStack.h 的头文件
如受限线性表中的”栈的链式存储“中的头文件所示。 - 建立一个 LinkStack.c 的源文件
如受限线性表中的"栈的链式存储"的源文件所示 - 建立一个 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)
中缀表达式和后缀表达式
示例:
- 建立一个 LinkStack.h 的头文件
如受限线性表中的”栈的链式存储“中的头文件所示。 - 建立一个 LinkStack.c 的源文件
如受限线性表中的"栈的链式存储"的源文件所示 - 建立一个 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*+
基于后缀表达式计算
示例:
- 建立一个 LinkStack.h 的头文件
如受限线性表中的”栈的链式存储“中的头文件所示。 - 建立一个 LinkStack.c 的源文件
如受限线性表中的"栈的链式存储"的源文件所示 - 建立 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