假设一个算术表达式中包含圆括号、方括号和花括号3种类型的括号,编写一个算法来判别,表达式中的括号是否配对,以字符“\0“作为算术表达式的结束符

思想:这道题是栈的应用类型,我们可以建立一个栈来保存'(','','{',通过遍历字符串如果是三个左括号其中一个则入栈,当遇到')''''}'则出栈配对,如果左右匹配,则遍历下一个元素,如果不匹配直接返回,如果遍历字符串结束,但栈中还有元素,则是左符号单身,如果已经空栈,但是又遍历到一个右括号,则是右括号单身

具体代码:

#include<stdio.h>

#include<stdbool.h>

#include<stdlib.h>

typedef struct LinkStack

{

char data;

struct LinkStack* next;

}LinkStack;

void InitStack(LinkStack** S)//初始化栈(不带头结点链表实现)

{

(*S) = NULL;

return;

}

bool Push(LinkStack** S,char ch)//入栈

{

if (ch == '(' || ch == '[' || ch == '{')

{

LinkStack* p = (LinkStack*)malloc(sizeof(LinkStack));

if (p == NULL)

return false;

//第一次入栈

if ((*S) == NULL)

{

p->data = ch;

p->next = NULL;

(*S) = p;

}

//后续入栈

else

{

p->data = ch;

p->next = (*S);

(*S) = p;

}

}

return true;

}

bool Pop(LinkStack** S)//出栈并且带回元素

{

if ((*S) == NULL)//空栈无法出栈

return false;

LinkStack* p = (*S);

//*x = p->data;

(*S) = p->next;

free(p);

return true;

}

LinkStack* GetTop(LinkStack* S)//返回栈顶指针

{

if (S == NULL)//空栈

return NULL;

LinkStack* p = S;

return p;

}

bool EmptyStack(LinkStack* S)//判断空栈

{

if (S == NULL)

return true;

return false;

}

void JudgeStack(LinkStack **S,char arr\[\])//判断

{

char* a = arr;

while (*a != '\0')

{

if (*a == '(' || *a == '[' || *a == '{')//如果当时是三个括号其中一个则入栈

Push(S, *a);

else if (EmptyStack(*S) == false && *a == ')' && GetTop((*S))->data == '(')//如果是'('则出栈

Pop(S);

else if (EmptyStack(*S) == false && *a == ')' && GetTop((*S))->data != '(')//如果不是则直接退出

{

printf("配对失败\n");

printf("%c %c\n",*a, GetTop((*S))->data);

return;

}

else if (EmptyStack(*S) == false && *a == ']' && GetTop((*S))->data == '[')//如果是'['则出栈

Pop(S);

else if (EmptyStack(*S) == false && *a == ']' && GetTop((*S))->data != '[')

{

printf("配对失败\n");

printf("%c %c\n", *a, GetTop((*S))->data);

return;

}

else if (EmptyStack(*S) == false && *a == '}' && GetTop((*S))->data == '{')//如果是'{'则出栈

Pop(S);

else if (EmptyStack(*S) == false && *a == '}' && GetTop((*S))->data != '{')

{

printf("配对失败\n");

printf("%c %c\n", *a, GetTop((*S))->data);

return;

}

else if (EmptyStack(*S) == true && (*a == ')' || *a == ']' || *a == '}'))//如果栈为空,且字符串中还有元素

printf("右括号单身\n");

a++;//向后遍历字符串

}

if (EmptyStack(*S) == false)//如果字符串已遍历结束但栈里还有元素

printf("左括号单身\n");

else

printf("配对成功\n");

return;

}

int main()

{

char arr\[\] = "(3 + 2) \* 5 + 3(]()";

LinkStack* S;//指向栈的指针

InitStack(&S);//初始化栈

JudgeStack(&S , arr);

return 0;

}

注:此代码中运用了大量的if-else语句,不是很美观(其实懒得改了),大家如果要引用可以自行优化代码

相关推荐
To_OC3 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC3 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK5 小时前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌18 小时前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局18 小时前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象18 小时前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局18 小时前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法
统计实现局18 小时前
dqrsl 拆解:拿着 QR 结果能算出哪 5 种东西
算法
统计实现局18 小时前
为什么 Cholesky 求逆比 Gauss-Jordan 快一倍——行列式溢出防护详
算法