栈的应用-----1. 就近匹配
叙述: 几乎所有的编译器都具有检测括号匹配的能力
如何实现编译器中的符号检测?
#include <stdio.h> int main () {int a[4][4]; int (*p)[4]; p=a[4]; return 0;}
算法思路:
- 从第一个字符开始扫描;
- 当遇到普通字符时忽略;
- 当遇见左括号时压入栈中,
- 当遇见右符号时,从栈中弹出栈顶符号,并进行匹配。
- 匹配成功:继续读入下一个字符;匹配失败:立即停止,并报错。
- 结束:
- 成功:所有字符扫描完毕,且栈为空;
- 失败:匹配失败或所有自负扫描完毕且栈非空。
1) 代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct StackNode 5 { 6 int data; 7 struct StackNode *next; 8 }StackNode,*LinkStackPtr; 9 10 typedef struct LinkStack 11 { 12 LinkStackPtr top; 13 int count; 14 }LinkStack; 15 16 //1. 初始化 17 LinkStack* init_linkStack() 18 { 19 LinkStack *s2=(LinkStack*)malloc(sizeof(LinkStack)); 20 s2->top=NULL; 21 s2->count=0; 22 return s2; 23 } 24 25 //2. 入栈 26 int push_linkStack(LinkStack*s2,int e) 27 { 28 LinkStackPtr node=(LinkStackPtr )malloc(sizeof(StackNode)); 29 node->data=e; 30 node->next=s2->top; 31 s2->top=node; 32 //cout<<s2->count; 33 s2->count++; 34 35 return 0; 36 } 37 38 //3. 出栈 39 int pop_linkStack(LinkStack*s2) 40 { 41 LinkStackPtr node=NULL; 42 //cout<<s2->top; 43 //cout<<s2->count; 44 if(s2->count==0) 45 return -1; 46 int a=s2->top->data; 47 s2->top=s2->top->next; 48 s2->count--; 49 50 51 52 return a; 53 } 54 55 //4. 遍历 56 int print_linkStack(LinkStack*s2) 57 { 58 LinkStack *ss=s2; 59 LinkStackPtr node=ss->top; 60 int k=ss->count; 61 while(k>0) 62 { 63 printf(" %5d",s2->top->data); 64 ss->top=ss->top->next; 65 k--; 66 } 67 return 0; 68 } 69 70 71 #include <iostream> 72 using namespace std; 73 74 int isLeft(char c) 75 { 76 int ret =0; 77 switch(c) 78 { 79 case '<': 80 case '{': 81 case '[': 82 case '(': 83 case '\'': // 单引号 84 case '\"': // 双引号 85 ret=1; 86 break; 87 default: 88 ret=0; 89 break; 90 } 91 return ret; 92 } 93 94 int isRight(char c) 95 { 96 int ret =0; 97 switch(c) 98 { 99 case '>': 100 case '}': 101 case ']': 102 case ')': 103 case '\'': // 单引号 104 case '\"': // 双引号 105 ret=1; 106 break; 107 default: 108 ret=0; 109 break; 110 } 111 return ret; 112 } 113 114 int match(char left,char right) 115 { 116 int ret=0; 117 118 switch (left) 119 { 120 case '<': 121 ret=(right=='>'); 122 break; 123 case '[': 124 ret=(right==']'); 125 break; 126 case '(': 127 ret=(right==')'); 128 break; 129 case '{': 130 ret=(right=='}'); 131 break; 132 case '\'': 133 ret=(right=='\''); 134 break; 135 case '\"': 136 ret=(right=='\"'); 137 break; 138 default: 139 ret=0; 140 break; 141 } 142 return ret; 143 } 144 145 int scanner(const char *code) 146 { 147 LinkStack *s2; 148 s2=init_linkStack(); 149 int ret=0; 150 int i=0; 151 152 while (code[i]!='\0') 153 { 154 if (isLeft(code[i])) 155 { 156 //int a=atoi(code[i]); 157 //char c=code[i]; 158 ret=push_linkStack(s2,code[i]); 159 } 160 if (isRight(code[i])) 161 { 162 //int a=atoi(code[i]); 163 //char c=code[i]; 164 char c=(char)pop_linkStack(s2); 165 166 if(!match(c,code[i])) 167 { 168 printf("%5c does not match!\n",code[i]); 169 ret=0; 170 break; 171 } 172 } 173 //cout<<code[i]; 174 i++; 175 //cout<<endl<<"i的大小: "<<i; 176 } 177 //cout<<endl<<"i的大小: "<<i; 178 //cout<<char(s2->top->data); 179 //cout<<s2->count; 180 //char a=code[i-1]; 181 //cout<< a; 182 if (s2->count==0) 183 { 184 printf("succeed\n"); 185 } 186 else 187 { 188 printf("Invalid code\n"); 189 } 190 191 192 return 0; 193 } 194 195 int main() 196 { 197 const char *code="#include <stdio.h> int main () {int a[4][4]; int (*p)[4]; p=a[4; return 0;aaaa"; 198 //const char *code="(1+1;)"; 199 //const char *code="(11;"; 200 201 scanner(code); 202 203 system("pause"); 204 return 0; 205 }
2) 运行结果