括号匹配算法

来源:互联网 发布:java static内存泄漏 编辑:程序博客网 时间:2024/05/19 13:18

检验括号是否匹配的方法可以用“期待的急迫程度”这个概念来描述。

  例如,考虑下列括号序列:

  [ ( [ ] [ ] ) ]

  1 2 3 4 5 6 7 8

  当计算机接受了第一个括号后,它期待着与其匹配的第八个括号的出现,然而等来的却是第二个括号,此时第一个括号“[”只能暂时靠边,而迫切等待与第二个括号相匹配的、第七个括号“)”的出现,类似地,因等来的是第三个括号“[”,其期待匹配的程度较第二个括号更急迫,则第二个括号也只能靠边,让位于第三个括号,显然第二个括号的期待急迫性高于第一个括号;在接受了第四个括号之后,第三个括号的期待得到满足,消解之后,第二个括号的期待匹配就成为当前最急迫的任务了,……依此类推。

  很显然,这样的一个处理过程和栈的特点非常吻合,因此,这个问题可以用栈来解决。

  解决思路

  1.在算法中设置一个栈,每次读入一个括号;

  2.若是右括号,则或者使置于栈顶的最急迫的期待得以消解,此时将栈顶的左括号弹出;或者是不合法的情况,此时将右括号压入;

  3.若是左括号,则作为一个新的更急迫的期待压入栈中,自然使原有的在栈中的所有未消解的期待的急迫性都降低一级;

  4.在算法的开始和结束时,栈应该为空。

代码1:

Stack是一个已实现的栈,可使用的相关类型和函数:
typedef char SElemType; // 栈Stack的元素类型
Status InitStack(Stack &s);
Status Push(Stack &s, SElemType e);
Status Pop(Stack &s, SElemType &e);
Status StackEmpty(Stack s);
Status GetTop(Stack s, SElemType &e);

 1 Status MatchCheck(SqList exp) 2 /* 顺序表exp表示表达式;                        */ 3 /* 若exp中的括号配对,则返回TRUE,否则返回FALSE */ 4 { 5     Stack s; 6     char e; 7  8     //逐个读入括号 9     for(int i=0;i<exp.length;i++)10     {11         if(exp.elem[i]=='('||exp.elem[i]=='{'||exp.elem[i]=='[')//若遇左括号,则直接入栈12         {            13             Push(s,exp.elem[i]);14         }15         else if(exp.elem[i]==')')//若遇右圆括号,则尝试匹配栈顶括号16         {            17             if(GetTop(s,e))18             {19                 if(e=='(')//匹配成功,左圆括号出栈20                 {21                     Pop(s,e);22                 }      23                 else//匹配不成功,右圆括号入栈24                 {25                     Push(s,exp.elem[i]);26                 }          27             }  28             else//栈为空,则将右括号入栈29             {30                 Push(s,exp.elem[i]);                31             } 32         }33         else if(exp.elem[i]=='}')//若遇右花括号,则尝试匹配栈顶括号34         {35             if(GetTop(s,e))36             {37                 if(e=='{')//匹配成功,左花括号出栈38                 {39                     Pop(s,e);40                 }      41                 else//匹配不成功,右花括号入栈42                 {43                     Push(s,exp.elem[i]);44                 }          45             }46             else47             {48                 Push(s,exp.elem[i]);49             } 50         }51         else if(exp.elem[i]==']')//若遇右方括号,则尝试匹配栈顶括号52         {53             if(GetTop(s,e))54             {55                 if(e=='[')//匹配成功,左方括号出栈56                 {57                     Pop(s,e);58                 }      59                 else//匹配不成功,右方括号入栈60                 {61                     Push(s,exp.elem[i]);62                 }          63             }64             else65             {66                 Push(s,exp.elem[i]);67             } 68         }69     }    70     if(StackEmpty(s))//当所有括号匹配成功时,栈应为空71     {72         return TRUE;73     }74     else75     {76         return FALSE;77     }78 }
代码2:

完整的C程序,该算法的时间复杂性为O(n),其中n为输入串的长度:

复制代码
  1 #include "stdio.h"
2 #include "string.h"
3 #include "stdlib.h"
4
5
6 #define StackSize 100 //假定预分配的栈空间最多为100个元素
7 #define MaxLength 100 //最大的字符串长度
8
9 typedef int DataType; //假定栈元素的数据类型为整数
10 typedef struct
11 {
12 DataType data[StackSize];
13 int top;
14 }SeqStack;
15
16 void Initial(SeqStack *S);
17 int IsEmpty(SeqStack *S);
18 int IsFull(SeqStack *S);
19 void Push(SeqStack *S, DataType x);
20 DataType Pop(SeqStack *S);
21 DataType Top(SeqStack *S);
22 void PrintMatchedPairs(char *expr);
23
24
25 void main(void)
26 {
27 char expr[MaxLength];
28 printf("请输入符号个数小于%d的表达式:\n",MaxLength);
29
30 gets(expr);
31
32 printf("括号对是:\n");
33
34 PrintMatchedPairs(expr);
35
36 return;
37 }
38
39 //置栈空
40 void Initial(SeqStack *S)
41 {
42 S -> top = -1;
43 }
44
45 //判断栈是否空
46 int IsEmpty(SeqStack *S)
47 {
48 return S -> top == -1;
49 }
50
51 //判断栈是否满
52 int IsFull(SeqStack *S)
53 {
54 return S -> top == StackSize -1;
55 }
56
57 //进栈
58 void Push(SeqStack *S, DataType x)
59 {
60 if(IsFull(S))
61 {
62 printf("栈上溢!");
63 exit(1);
64 }
65
66 S -> data[++ S -> top] = x;
67
68 return;
69 }
70
71 //出栈
72 DataType Pop(SeqStack *S)
73 {
74 if(IsEmpty(S))
75 {
76 printf("栈为空!");
77 return -1;
78 }
79
80 return S -> data[S -> top--]; //栈顶指针加1后将x入栈
81 }
82
83 //取栈顶元素
84 DataType Top(SeqStack *S)
85 {
86 if(IsEmpty(S))
87 {
88 printf("栈为空!");
89 exit(1);
90 }
91
92 return S -> data[S -> top];
93 }
94
95 //括号匹配
96 void PrintMatchedPairs(char *expr)
97 {
98 SeqStack S;
99 int i , j , length = strlen(expr);
100
101 Initial(&S);
102
103 for(i = 1 ; i <= length ; i++)
104 {
105 if(expr[i - 1] == '(')
106 {
107 Push(&S,i);
108 }
109 else if(expr[i - 1] == ')')
110 {
111 j = Pop(&S);
112 if(j == -1)
113 {
114 printf("没有对应第%d个右括号的左括号\n", i);
115 }
116 else
117 {
118 printf("%d %d\n",i,j);
119 }
120 }
121 }
122
123 while(!IsEmpty(&S))
124 {
125 j = Pop(&S);
126 printf("没有对应第%d个左括号的右括号\n", j);
127 }
128 }
代码3:

算法:检测表达式中的字符,若是左括号就入栈,如果是右括号就出栈一个元素与其配对,配对成功则继续访问下一个字符,否则退出。出现非括号字符则跳过。

[cpp] view plaincopyprint?
  1. #include <stdio.h>  
  2. #include <malloc.h>   //malloc,realloc  
  3. #include <math.h>     //含有overflow  
  4. #include <process.h>  //exit()  
  5. #define S_SIZE 100   //栈的空间大小  
  6. #define STACKINCREAMENT 10//增加空间  
  7. struct SqStack{  
  8.     int *base; //栈底  
  9.     int *top;  //栈顶  
  10.     int stacksize;   //栈当前的存储空间  
  11. };  
  12. void main()  
  13. {//子函数声明  
  14.     void InitStack(SqStack &S);//初始化空栈  
  15.     int StackEmpty(SqStack S);//判空  
  16.     void push(SqStack &S,int e);//进栈  
  17.     void pop(SqStack &S,int &e);//出栈  
  18.     //主函数开始  
  19.     SqStack s;//初始化空栈  
  20.     InitStack(s);  
  21.     char ch[100],*p;int e;  
  22.     p=ch;  
  23.     printf("输一个含义有()[]{}的括号表达式:\n");  
  24.     gets(ch);  
  25.     while(*p)  
  26.     {   
  27.         switch (*p)  
  28.         {  
  29.         case '{':  
  30.         case '[':  
  31.         case '(': push(s,*p++);break;//只要是左括号就入栈  
  32.         case '}':  
  33.         case ']':  
  34.         case ')':pop(s,e);  
  35.                  if ((e=='{' && *p=='}') ||(e=='[' && *p==']') || (e=='(' && *p==')'))  
  36.                  p++;  
  37.                  else  
  38.                  {printf("括号不匹配!");exit(OVERFLOW);}  
  39.                  break;  
  40.         default :p++;//其他字符就后移  
  41.         }  
  42.     }  
  43.     if (StackEmpty(s))  
  44.       printf("括号匹配成功");  
  45.     else  
  46.       printf("缺少右括号!");  
  47.     printf("\n");  
  48. }  
  49. void InitStack(SqStack &S)  
  50. {S.base=(int *)malloc(S_SIZE*sizeof(int));  
  51. S.stacksize=S_SIZE;  
  52. S.top=S.base;//初始化空栈  
  53. }  
  54. int StackEmpty(SqStack S)  
  55. {  
  56.     if(S.base==S.top)  
  57.         return 1;  
  58.     else  
  59.         return 0;  
  60. }  
  61. void push(SqStack &S,int e)  
  62. {//进栈  
  63.     if(S.top-S.base>=S.stacksize)  
  64.     {S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(int));  
  65.     S.top=S.base+S.stacksize;  
  66.     S.stacksize+=STACKINCREAMENT;}  
  67.     *(S.top)=e;  
  68.     S.top++;        
  69. }  
  70. void pop(SqStack &S,int &e)  
  71. {//出栈  
  72.     if(S.base!=S.top)  
  73.     {S.top--;  
  74.     e=*S.top;}  
  75. }  

0 0