您的位置:首页 > 其它

栈解决------括号匹配问题和逆波兰表达式

2018-08-20 16:09 78 查看

所需知识


字符串

一.括号匹配问题

❀思路分析

有如下四组字符串
如何检测左右括号顺序与个数是否匹配

char a[] = "(())abc{[(])}";
char b[] = "(()))abc{[]}";
char c[] = "(()()abc{[]}";
char d[] = "(())abc{[]()}";

1、解决:

(1)、当读到一个左括号的字符,包括‘(’,‘{’,‘[’时,将这个字符入栈,当检测到右括号字符时,包括‘)’,‘}’,’]’时,检测栈顶元素是否为与之匹配的左括号,若是,证明这一对括号匹配,将这个左括号出栈继续检测,检测到其他字符,如字母数字,直接跳过,不做任何处理。
(2)、左右括号不匹配:如果检测到右括号时,取栈顶元素中的左括号,发现不是与之对应的左括号,说明不匹配。
(3)、右括号比左括号多:如果检测到右括号时,取栈顶元素中的左括号,发现栈已空,说明右括号多余左括号。
(4)、左括号比右括号多:当所有字符都已经读完,发现栈内仍有左括号,说明左括号比右括号多。
(5)、匹配成功:当中间无其他情况发生,且读完字符后,栈为空,说明匹配成功。

2、具体实现

#include <stdio.h>
//括号匹配
#define MAX 20
typedef char DataType;
typedef struct Stack
{
DataType arr[MAX];
int top;

}Stack;
//初始化栈
void InitStack(Stack * s)
{
s->top = 0;
}
//取栈顶元素
DataType StackTop(Stack * s)
{
if (s->top == 0)
{
return '*';
}
return s->arr[s->top - 1];
}
//清空栈
void Empty(Stack * s)
{
s->top = 0;
}
//入栈
void PushStack(Stack * s, DataType c)
{
if (s->top == MAX)
{
printf("栈已满,无法再入\n");
return;
}
s->arr[s->top] = c;
s->top++;
}
//判断栈是否空,空返回1
int  EmptyStack(Stack *s)
{
if (s->top == 0)
return 1;
return 0;
}
//出栈
void PopStack(Stack * s)
{
if (s->top == 0)
{
printf("已空,无法再出栈\n");
return;
}
s->top--;
}
void The(char arr[],Stack * s)
{
int  i = 0;
for ( i = 0; arr[i]!=0;i++)
{
if (arr[i] == '(')
{
PushStack(s, arr[i]);
continue;
}
if (arr[i] == '{')
{
PushStack(s, arr[i]);
continue;
}
if (arr[i] == '[')
{
PushStack(s, arr[i]);
continue;
}
if (arr[i] == ')')
{

if (StackTop(s) == '(')
{
PopStack(s);
}
else if (StackTop(s) == '*')
{
printf("右括号比左括号多\n");
return;
}
else
{
printf("左右括号不匹配\n");
return;
}
}
if (arr[i] == ']')
{
if (StackTop(s) == '[')
{
PopStack(s);
}
else if (StackTop(s) == '*')
{
printf("右括号比左括号多\n");
return;
}
else
{
printf("左右括号不匹配\n");
return;
}
}
if (arr[i] == '}')
{
if (StackTop(s) == '{')
{
PopStack(s);
}
else if (StackTop(s) == '*')
{
printf("右括号比左括号多\n");
return;
}
else
{
printf("左右括号不匹配\n");
return;
}
}
}
if (EmptyStack(s)&&arr[i]==0)
{
printf("匹配成功\n");
}
else
{
printf("左括号比右括号多\n");
}

}
int main()
{
//

char a[] = "(())abc{[(])}";
char b[] = "(()))abc{[]}";
char c[] = "(()()abc{[]}";
char d[] = "(())abc{[]()}";
Stack s;
InitStack(&s);
The(a,&s);
Empty(&s);
The(b, &s);
Empty(&s);
The(c, &s);
Empty(&s);
The(d, &s);
system("pause");
return 0;
}

二、逆波兰表达式

❀思路分析

以12*(3+4)-6+8/2 —–> 12 3 4 + *6 - 8 2/ +为例

(1)、读到数字时,将数字压栈

(2)、读到+,-,*,/的操作符时,取出栈顶的前两位数字,进行运算操作后,将其结果压栈

具体实现

#ifndef __REVERSE_ORDER_EXPRESSION_H__
//逆波兰表达式
//12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAXSIZE 15
typedef enum Operation
{
ADD,
SUB,
MUL,
DIV,
DATA
}Way;
typedef int DataType;
typedef struct Cell
{
Way way;
DataType data;
}Cell;
//进行逆波兰填栈操作
//创建栈
typedef struct Stack
{
DataType data[MAXSIZE];
int top;
}Stack;
//栈的初始化
void InitStack(Stack * s)
{
s->top = 0;
}
//入栈
void PushStack(Stack * s, DataType d)
{
assert(s);
if (s->top == MAXSIZE)
{
printf("栈已满,无法入\n");
return;
}
s->data[s->top] = d;
s->top++;

}
//取栈顶元素,并出栈
DataType TopStack(Stack *s)
{
assert(s);
if (s->top == 0)
{
printf("无元素,无法取栈顶\n");
return ;
}
s->top--;
return s->data[s->top];
}
DataType order(Cell arr[],int size,Stack *s)
{
int i = 0;
int a = 0, b = 0;
for (i = 0; i<size;i++)
{
a = 0;
b = 0;
switch(arr[i].way)
{
case ADD:
{
a = TopStack(s);
b = TopStack(s);
PushStack(s, b + a);
break;
}
case SUB:
{
a = TopStack(s);
b = TopStack(s);
PushStack(s, b - a);
break;
}
case MUL:
{
a = TopStack(s);
b = TopStack(s);
PushStack(s, b * a);
break;
}
case DIV:
{
a = TopStack(s);
b = TopStack(s);
PushStack(s, b / a);
break;
}
case DATA:
{
PushStack(s, arr[i].data );
break;
}
default:
{
printf("给定值错误,请重新给定\n");
break;
}
}
}
return TopStack(s);
}
int main()
{
//12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +
//给定数列操作12 3 4 + *6 - 8 2/ +
Stack s;
Cell arr[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 },
{ ADD, 0 }, { MUL, 0 }, { DATA, 6 }, { SUB, 0 }, {DATA,8}, {DATA,2}, {DIV,0}, {ADD,0} };
int size = sizeof(arr) / sizeof(arr[0]);
InitStack(&s);
printf("该表达式12*(3+4)-6+8/2 -----> 12 3 4 + *6 - 8 2/ +的值为%d \n", order(arr, size, &s));
system("pause");
return 0;
}

#endif  //__REVERSE_H__

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: