编写一栈程序,从标准输入得到一个缺少左括号的表达式并打印出补全括号之后的中序表达式。
例如:
给定输入:
1+2)*3-4)*5-6)))
你的程序输出:
((1+2)*((3-4)*(5-6)))
要求:
(1) 初始化栈s。
(2) 从键盘输入一个缺少左括号的表达式,并打印出补全括号之后的中序表达式。
要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。
代码:
struct.h
1 //结构体定义 2 3 4 #ifndef STR_H 5 #define STR_H 6 7 #include "common.h" 8 #define MAX 1000 9 10 typedef struct 11 { 12 char stack[MAX]; 13 int top; 14 }SeqStack; 15 16 17 #endif
common.h
1 //全体公用的头文件 2 3 #ifndef COMMON_H 4 #define COMMON_H 5 6 #include<stdio.h> 7 #include<stdlib.h> 8 #include<string.h> 9 #include<windows.h> 10 #include<malloc.h> 11 12 #define ERROR 0 13 #define OK 1 14 #define WR -1 15 16 #endif 17 18 //windows.h提供了sleep()和system("cls") 19 //用来暂定和清屏
functions.h
1 #ifndef FUN_H 2 #define FUN_H 3 4 5 #include "common.h" 6 #include "struct.h" 7 8 9 int menu_select(void); 10 void InitStack(SeqStack *s); 11 int Push(SeqStack *s,char x); 12 int Pop(SeqStack *s,char *x); 13 void My_Push(SeqStack *s); 14 void My_Pop(SeqStack *s); 15 void Output_History(void); 16 17 void Gotoxy(int x,int y); 18 void Wrong(void); 19 void Line(void); 20 int Judge(char x); 21 void Tips(void); 22 23 #endif
main.c
1 #include "common.h" 2 #include "struct.h" 3 #include "functions.h" 4 5 6 int main(void) 7 { 8 SeqStack s; 9 s.top=-1; 10 Tips(); 11 for(;;) 12 { 13 switch(menu_select()) 14 { 15 case 0: 16 Line(); 17 return 0; 18 case 1: 19 InitStack(&s);break; 20 case 2: 21 Line(); 22 My_Push(&s);break; 23 case 3: 24 My_Pop(&s);break; 25 case 4: 26 Output_History(); 27 } 28 system("cls"); 29 } 30 }
functions.c
1 /******************************************************************** 2 Author:buting Ver:1.2 Data:2016.4.8 3 Description: 4 a.可以通过历史数组访问历史输入与输出 5 b.输入函数中是间接输入到栈中,所以可以避免掉非法输入 6 c.实测非法输入提示与栈满提示正常显示 7 Node: 8 a.优化显示时间及排序 9 b.添加提示页 10 c.添加显示样例输入的询问? 待定!! 11 **********************************************************************/ 12 13 #include "common.h" 14 #include "struct.h" 15 #include "functions.h" 16 17 char History_Push[MAX*2],History_Pop[MAX*2]; 18 /* 这里定义了两个全局变量,用来实现查看历史输入输出的功能*/ 19 20 21 //菜单驱动程序 22 int menu_select(void) 23 { 24 int x; 25 system("cls");Line(); 26 //-------------------- 27 printf(" ->补全括号表达式<- \n"); 28 printf(" 1、初始化栈 \n"); 29 printf(" 2、录入数据 \n"); 30 printf(" 3、读出数据 \n"); 31 printf(" 4、历史数据 \n"); 32 printf(" 0、退出栈列 "); 33 Line(); 34 printf("\n");; 35 do 36 { 37 printf("请依次选择序号:"); 38 scanf("%d",&x); 39 if(x>=0&&x<5) 40 break; 41 Wrong(); 42 printf("\r非法数据! "); 43 Sleep(1000); 44 //Gotoxy(0,11); 45 printf("\r "); 46 Gotoxy(0,10); 47 printf(" \r"); 48 }while(OK); 49 return x; 50 } 51 52 53 54 //初始化 55 void InitStack(SeqStack *s) 56 { 57 s->top=-1; 58 Line(); 59 printf("\n成功!\n"); 60 Line(); 61 Sleep(1000); 62 system("cls"); 63 } 64 65 //进栈 66 int Push(SeqStack *s,char x) 67 { 68 if(s->top==MAX-1) 69 return ERROR; 70 s->top++; 71 s->stack[s->top]=x; 72 return OK; 73 } 74 75 //出栈 76 int Pop(SeqStack *s,char *x) 77 { 78 if(s->top==-1) 79 return ERROR; 80 else 81 *x=s->stack[(s->top)--]; 82 return OK; 83 } 84 85 //输入数据 86 void My_Push(SeqStack *s) 87 { 88 int i,ture=0,times,n; 89 char Wrong_times[MAX]; 90 while(!ture) 91 { 92 system("cls");Line(); 93 getchar(); 94 printf("\n请输入缺左括号的表达式:\n"); 95 gets(History_Push); 96 n=strlen(History_Push); 97 for(i=times=0;i<n;i++) 98 { 99 if(History_Push[i]>=40&&History_Push[i]<=57) //40-57 100 { 101 if((History_Push[i]!=44)||(History_Push[i]!=46)) //44:, 46:. 102 { 103 if(!Push(s,History_Push[i])) 104 { 105 Wrong();ture=-2; 106 printf("\n栈满!\n以下数据未能录入:\n"); 107 for(;i<n;i++) 108 printf("%c",History_Push[i]); 109 printf("\n"); 110 Sleep(5000); 111 break; 112 } 113 }else{ 114 Wrong_times[times]=History_Push[i]; 115 times++;ture=-1; 116 } 117 }else{ 118 Wrong_times[times]=History_Push[i]; 119 times++;ture=-1; 120 121 } 122 } 123 if(ture==-1) 124 { 125 Wrong_times[times]=‘\0‘; 126 Line();Sleep(50); 127 printf("\n您的输入存在非法输入。");Sleep(50); 128 printf("\n\n以下数据未能录入:\n\n"); 129 puts(Wrong_times);Sleep(50); 130 printf("\n请检查是否存在非法字符\n");Sleep(50); 131 Line();Sleep(50); 132 printf("\n"); 133 for(i=0;i<10;i++) 134 { 135 printf("还有%d秒进入菜单",10-i); 136 Gotoxy(0,18); 137 Sleep(1000); 138 } 139 printf("\n"); 140 }else 141 ture=1; 142 } 143 Line(); 144 } 145 146 /* 147 输入部分存在错误 回头再修!!!!!!!!!!!!!!!!!! 148 void My_Push(SeqStack *s) 149 { 150 int i=0; 151 system("cls");Line(); 152 //-------------------- 153 printf(" 请 输 入 数 据\n"); 154 while((scanf("%c",&History_Push[i++]))!=EOF) //先将数据存到历史数组中 155 { //判断输入数据的合法性,如果不合法i--,重新覆盖数据 156 if(History_Push[i-1]>=40&&History_Push[i-1]<=57) //40-57 157 { 158 if((History_Push[i-1]!=44)||(History_Push[i-1]!=46)) //44:, 46:. 159 { 160 if(Push(s,History_Push[i-1])) 161 { 162 Wrong(); 163 printf("栈满!拒绝输入。\n"); 164 break; 165 } 166 }else{ 167 Wrong(); 168 printf("非法输入!"); 169 printf("\t "); 170 i--; 171 } 172 }else{ 173 Wrong(); 174 printf("非法输入!"); 175 printf("\t "); 176 i--; 177 } 178 } 179 History_Push[i]=‘\0‘; //为末尾补上结束标志 180 Line(); 181 Sleep(500); 182 system("cls"); 183 } 184 */ 185 186 //补括号 187 //形如 6+5))) 的输入 188 //补成 (((6+5))) 189 void My_Pop(SeqStack *s) 190 { 191 int right=0,i=0,wrong; 192 char Temp[MAX*2],temp; 193 system("cls");Line(); 194 while(OK) 195 { 196 wrong=Pop(s,&temp); /*pop在栈空的情况下返回0*/ 197 if(wrong&&(temp==‘)‘)){ 198 right++; /*right记录右括号的数目*/ 199 Temp[i++]=temp; 200 }else if(wrong&&temp<=‘10‘&&temp>=‘0‘) /*出栈的为数字*/ 201 Temp[i++]=temp; 202 else if(wrong&&(temp==‘+‘||temp==‘-‘)) /*出栈的为+ -*/ 203 Temp[i++]=temp; 204 else if(wrong&&(temp==‘*‘||temp==‘/‘)){ /*出栈的为* /*/ 205 if(right!=0){ 206 Temp[i++]=‘(‘; /*先存一左括号 */ 207 right--; /*匹配了一个,右括号数目减一*/ 208 } 209 Temp[i++]=temp; 210 }else if(right!=0&&wrong==0){ /*此情况是形如 6+3))) 的输入*/ 211 do{ 212 Temp[i++]=‘(‘; 213 }while((--right)!=0); /*剩多少补多少*/ 214 break; 215 }else if(right==0&&wrong==0) 216 break; 217 //else 218 // exit(0); 219 } 220 Temp[i]=‘\0‘; 221 // puts(Temp); 222 i=strlen(Temp)-1; 223 printf("\n输出结果\n\n"); 224 for(wrong=0;i>=0;i--,wrong++){ 225 printf("%c",Temp[i]); 226 History_Pop[wrong]=Temp[i]; /*从左到右的顺序存放*/ 227 } 228 History_Pop[wrong]=‘\0‘; 229 printf("\n"); 230 Line(); 231 Sleep(3000); 232 system("cls"); 233 } 234 235 //查看历史 236 //全局变量里的元素会被置为0 237 void Output_History(void) 238 { 239 char x; 240 Line(); 241 printf("\n历史输入:"); 242 puts(History_Push); 243 printf("历史输出:"); 244 puts(History_Pop); 245 Line(); 246 printf("\n退出历史:(y/n)\n"); 247 while(getchar()!=‘\n‘); 248 scanf("%c",&x); 249 if(!Judge(x)) 250 Sleep(8000); 251 Line(); 252 } 253 254 255 //将光标移动到坐标为(x,y)的地方 256 void Gotoxy(int x,int y) 257 { 258 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 259 HANDLE hConsoleOut; 260 hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); 261 GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo); 262 csbiInfo.dwCursorPosition.X = x; 263 csbiInfo.dwCursorPosition.Y = y; 264 SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); 265 } 266 267 //打印-------------------- 268 void Line(void) 269 { 270 char a[30]="--------------------"; 271 int i; 272 printf("\n"); 273 for(i=strlen(a);i>=0;i--) 274 { 275 printf("\r"); 276 printf("%s",&a[i]); 277 Sleep(20); 278 } 279 printf("\n"); 280 } 281 282 //输入错误的信息 283 void Wrong(void) 284 { 285 char wrong[30]="# WRONG # "; 286 int i; 287 for(i=strlen(wrong);i>=0;i--) 288 { 289 printf("\r "); 290 printf("%s ",&wrong[i]); 291 Sleep(30); 292 } 293 Sleep(800); 294 } 295 296 //判断输入的是否 297 int Judge(char x) 298 { 299 if(x==‘Y‘||x==‘y‘) 300 return 1; 301 else if(x==‘N‘||x==‘n‘) 302 return 0; 303 else 304 Wrong(); 305 return 0; 306 } 307 308 //界面提示 309 void Tips(void) 310 { 311 int i; 312 Line();Sleep(50); 313 printf("欢迎进入括号补全程序\n");Sleep(50); 314 printf("下面是一些小提示:\n");Sleep(50); 315 printf("1.请按照输入提示进行\n");Sleep(50); 316 printf("2.对先输入*或/的支持较差\n");Sleep(50); 317 printf("3.注意!中文括号与英文括号不同\n");Sleep(50); 318 Line();Sleep(50); 319 printf("\n"); 320 for(i=0;i<10;i++) 321 { 322 printf("还有%d秒进入菜单",10-i); 323 Gotoxy(0,10); 324 Sleep(1000); 325 } 326 system("cls"); 327 }
时间: 2024-10-17 13:35:03