21、栈的应用-就近匹配
main.c
/* 就近匹配,找出不匹配的符号用箭头A标注出来 这里只写了小括号的匹配 */ #define _CRT_SECURE_NO_WARNING #include<stdio.h> #include<stdlib.h> #include<string.h> #include"Stack.h" typedef struct MYCHAR { StackNode 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() { //char* str1 = "#include<stdio.h> int main(){int a[4][4];int (*p)[4];p=a[0];return 0;}"; char* str = "1+2+6(desa)ads)e(rfsd)"; //创建栈容器 LinkStack* stack = InitStack(); char* p = str; SElemType* e = (SElemType*)malloc(sizeof(SElemType)); int index = 0; while (*p != '\0') { //如果是左括号 直接进栈 if (IsLeft(*p)) { Push(stack, (StackNode*)CreatMyChar(p, index)); } //如果是右括号 从栈顶弹出元素 判断是不是左括号 if (IsRight(*p)) { if (StackLength(stack) > 0) { MyChar* mychar = (MyChar*)GetTop(stack); if (IsLeft(*(mychar->pAddres))) { Pop(stack, e); free(mychar); } } else { printf("右括号没有匹配的左括号:\n"); ShowError(str, index); break; } } p++; index++; } while (StackLength(stack) > 0) { MyChar* mychar = (MyChar*)GetTop(stack); printf("左括号没有匹配的右括号:\n"); ShowError(str, mychar->index); Pop(stack, e); free(mychar); } free(e); printf("\n"); system("pause"); return 0; }
stack.h
#ifndef STACK_H #define STACK_H #include<stdio.h> #include<stdlib.h> #include<string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef void* SElemType; typedef int Status; //初始化结构 typedef struct StackNode { SElemType data; struct StackNode* next; }StackNode, *LinkStackPtr; typedef struct LinkStack { StackNode* top; int count; }LinkStack; //初始化操作,建立一个空栈 LinkStack* InitStack(); //将栈清空 void ClearStack(LinkStack *s); //销毁 void DestoryStack(LinkStack *s); //若栈为空,返回TRUE,否则返回false Status IsEmpty(LinkStack s); //若栈存在且非空,返回S的栈顶元素 void* GetTop(LinkStack *s); //插入元素e为新的栈顶元素 Status Push(LinkStack *s, SElemType e); //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR Status Pop(LinkStack *s, SElemType *e); //返回栈S的元素个数 Status StackLength(LinkStack *s); //打印 void PrintfStack(LinkStack *s); #endif
stack.c
#include"Stack.h" //初始化操作,建立一个空栈 LinkStack* InitStack() { LinkStack *s = (LinkStack*)malloc(sizeof(LinkStack)); s->count = 0; s->top = (StackNode*)malloc(sizeof(StackNode)); s->top->data = NULL; s->top->next = NULL; return s; } //将栈清空 void ClearStack(LinkStack *s) { } //销毁 void DestoryStack(LinkStack *s) { if (s == NULL) { return; } LinkStackPtr p; p = s->top;//将栈顶结点赋值给p while (p != NULL) { LinkStackPtr pNext = p->next; free(p);//释放结点p p = pNext; } s->count = 0; free(s); } //若栈为空,返回TRUE,否则返回false Status IsEmpty(LinkStack s) { if (s.top->next == NULL) { return TRUE; } return FALSE; } //若栈存在且非空,返回S的栈顶元素 void* GetTop(LinkStack *s) { if (s == NULL) { return NULL; } return s->top->data; } //插入元素e为新的栈顶元素 Status Push(LinkStack *s, SElemType e) { LinkStackPtr a = (LinkStackPtr)malloc(sizeof(StackNode)); a->data = e; a->next = s->top;//把当前的栈顶元素赋给新结点的直接后继 s->top = a;//将新结点a赋值给栈顶指针 s->count++; return OK; } //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR Status Pop(LinkStack *s, SElemType *e) { StackNode* p; if (IsEmpty(*s)) { return ERROR; } *e = s->top->data; p = s->top;//将栈顶结点赋值给p s->top = p->next;//使得栈顶指针下移一位,指向后一结点 free(p);//释放结点p s->count--; return OK; } //返回栈S的元素个数 Status StackLength(LinkStack *s) { int j = s->count; return j; }
VS2015运行结果: