RH.h
1 #ifndef _MRCHEN_RP_H_ 2 #define _MRCHEN_RP_H_ 3 #include "stdio.h" 4 #include "stdlib.h" 5 #include "malloc.h" 6 #include "string.h" 7 #include "iostream" 8 #include <stack> 9 using namespace std; 10 #ifndef __cplusplus 11 typedef int BOOL; 12 #ifndef TRUE 13 #define TRUE 1 14 #endif 15 #ifndef FALSE 16 #define FALSE 0 17 #endif 18 #else 19 typedef bool BOOL; 20 #ifndef TRUE 21 #define TRUE true 22 #endif 23 #ifndef FALSE 24 #define FALSE false 25 #endif 26 #endif 27 28 //用于子串连接的结构 29 typedef struct _tagSubExp{ 30 char *exp_p; 31 struct _tagSubExp*next; 32 }SUB_EXP,*PSUB_EXP; 33 34 extern stack<PSUB_EXP> s1;//存放表达式 35 extern stack<PSUB_EXP> s2;//存放括号和运算符 36 /*子串出栈*/ 37 BOOL pop_exp(PSUB_EXP*,BOOL); 38 /*子串入栈*/ 39 BOOL push_exp(PSUB_EXP,BOOL); 40 /*合并三个子串*/ 41 BOOL cat_exp(PSUB_EXP,PSUB_EXP,PSUB_EXP); 42 /*一次获取中缀表达式中的子串*/ 43 BOOL get_next(PSUB_EXP*,char*); 44 /*获取中缀表达式*/ 45 char * get_exp(char *exp_p); 46 /*将中缀表达式转换为后缀表达式*/ 47 char * convert_exp(char *exp,char *convert_sz); 48 /*打印逆波兰表达式*/ 49 void print_exp(PSUB_EXP); 50 51 #endif
RH.cpp
1 // 逆波兰运算.cpp : Defines the entry point for the console application. 2 #include "stdafx.h" 3 #include "RP.h" 4 5 stack<PSUB_EXP> s1; 6 stack<PSUB_EXP> s2; 7 8 /*打印后缀表达式*/ 9 void print_exp(PSUB_EXP p) 10 { 11 while(p){ 12 printf("%s ",p->exp_p); 13 p = p->next; 14 } 15 printf("\n"); 16 } 17 18 /*将中缀表达式转换为后缀表达式*/ 19 char * convert_exp(char *exp,char *convert_p) 20 { 21 char ch; 22 PSUB_EXP p; 23 PSUB_EXP sub_p; 24 PSUB_EXP f_p, s_p, t_p; 25 //判断参数时候合法 26 if(convert_p==NULL||exp==NULL || *exp == '\n'){ 27 return NULL; 28 } 29 //循环读取中缀表达式 30 while( TRUE==get_next(&sub_p,exp) ){ 31 //判断读取到的是数字串还是运算符还是括号 32 ch = *(sub_p->exp_p); 33 switch(ch){ 34 //如果是 + , 则入栈 35 case '+': 36 { 37 push_exp(sub_p,FALSE); 38 } 39 break; 40 //如果是 - , 则入栈 41 case '-': 42 { 43 push_exp(sub_p,FALSE); 44 } 45 break; 46 //如果是 * , 则入栈 47 case '*': 48 { 49 //先入栈 50 push_exp(sub_p,FALSE); 51 //然后读取下个字串 52 get_next(&sub_p,exp); 53 //如果是数字串,这进行合并处理 54 ch = *(sub_p->exp_p); 55 if(ch >= '0' && ch <= '9' ){ 56 s_p = sub_p; 57 pop_exp(&t_p,FALSE); 58 pop_exp(&f_p,TRUE); 59 cat_exp(f_p,s_p,t_p); 60 push_exp(f_p,TRUE); 61 }else if(ch == '('){//如果是括号,则入栈 62 push_exp(sub_p,FALSE); 63 } 64 } 65 break; 66 case '/': 67 { 68 //先入栈 69 push_exp(sub_p,FALSE); 70 //然后读取下个字串 71 get_next(&sub_p,exp); 72 //如果是数字串,这进行合并处理 73 ch = *(sub_p->exp_p); 74 if(ch >= '0' && ch <= '9' ){ 75 s_p = sub_p; 76 pop_exp(&t_p,FALSE); 77 pop_exp(&f_p,TRUE); 78 cat_exp(f_p,s_p,t_p); 79 push_exp(f_p,TRUE); 80 }else if(ch == '('){//如果是括号,则入栈 81 push_exp(sub_p,FALSE); 82 } 83 } 84 break; 85 case '('://如果是前括号 则入栈 86 { 87 push_exp(sub_p,FALSE); 88 } 89 break; 90 case ')'://如果是否括号,这进行相应处理 91 { 92 //从栈中弹出两表达式串,一个运算符串,然后合并并押入栈中,直到弹出的运算符是 '(' 93 while(pop_exp(&t_p,FALSE)&&*(t_p->exp_p)!='('){ 94 pop_exp(&s_p,TRUE); 95 pop_exp(&f_p,TRUE); 96 cat_exp(f_p,s_p,t_p); 97 push_exp(f_p,TRUE); 98 } 99 //接着弹出后续的运算符 100 pop_exp(&t_p,FALSE); 101 //如果是 * 或 / , 则再从栈中弹出两表达式,并合并 然后入栈 102 if(*(t_p->exp_p)=='*'||*(t_p->exp_p)!='/'){ 103 pop_exp(&s_p,TRUE); 104 pop_exp(&f_p,TRUE); 105 cat_exp(f_p,s_p,t_p); 106 push_exp(f_p,TRUE); 107 }else{//如果不是 * 或 / , 则将运算符方入栈中 108 push_exp(t_p,FALSE); 109 } 110 } 111 break; 112 default: 113 {//如果是数字串 , 则 入栈 114 push_exp(sub_p,TRUE); 115 } 116 break; 117 } 118 } 119 //将栈中剩下的数据排列成后缀形式 120 while(pop_exp(&t_p,FALSE)){ 121 pop_exp(&s_p,TRUE); 122 pop_exp(&f_p,TRUE); 123 cat_exp(f_p,s_p,t_p); 124 push_exp(f_p,TRUE); 125 } 126 //将转换好的后缀表达式存放到新的空间中 127 while(f_p){ 128 strcat(convert_p,f_p->exp_p); 129 p = f_p; 130 f_p = f_p->next; 131 getchar(); 132 free(p); 133 } 134 return convert_p; 135 } 136 137 /*获取中缀表达式*/ 138 char* get_exp(char *exp_p) 139 { 140 char tmp_exp_sz[64+1]; 141 char *p = tmp_exp_sz; 142 int i; 143 //输入中缀表达式 144 fgets(p,64,stdin); 145 //然后解析中缀表达式 , 并以 '\0'分割每个子串 146 for(i=0; *p!='\0' ; i++){ 147 if(*p >= '0' && *p <= '9'){ 148 exp_p[i] = *p; 149 }else{ 150 if(*p != ' '){ 151 exp_p[i++] = NULL; 152 exp_p[i++] = *p; 153 exp_p[i] = NULL; 154 } 155 } 156 p++; 157 } 158 return 0; 159 } 160 /*一次获取中缀表达式中的子串*/ 161 BOOL get_next(PSUB_EXP * sub_p,char*exp_p) 162 { 163 static char *p = exp_p; 164 if(*p == '\n'){ 165 return FALSE; 166 } 167 //申请保存串信息的节点 168 *sub_p = (PSUB_EXP)calloc(1,sizeof(SUB_EXP)); 169 (*sub_p)->exp_p = p; 170 //获取下一个串 171 p += strlen(p); 172 while(*(++p) == NULL); 173 return TRUE; 174 } 175 176 /*子串出栈*/ 177 BOOL pop_exp(PSUB_EXP* sub_pp,BOOL flag) 178 { 179 if(flag == TRUE){// 从s1栈中弹出表达式串 180 if(s1.empty()) 181 return FALSE; 182 *sub_pp = (PSUB_EXP)s1.top(); 183 s1.pop(); 184 }else{//从s2中弹出运算符串 185 if(s2.empty()) 186 return FALSE; 187 *sub_pp = (PSUB_EXP)s2.top(); 188 s2.pop(); 189 } 190 return TRUE; 191 } 192 193 /*子串入栈*/ 194 BOOL push_exp(PSUB_EXP sub_p,BOOL flag) 195 { 196 if(flag == TRUE){//如果是表达式串则放入s1栈中 197 s1.push(sub_p); 198 }else{ 199 s2.push(sub_p);//如果是表达式串则放入s2栈中 200 } 201 return TRUE; 202 } 203 204 /*合并三个子串*/ 205 BOOL cat_exp(PSUB_EXP f_p,PSUB_EXP s_p,PSUB_EXP t_p) 206 { 207 PSUB_EXP p; 208 if(!f_p || !s_p || !t_p){ 209 return FALSE; 210 }else{ 211 //按 f_p:s_p:t_p 的顺序合并 212 p = f_p; 213 while(p->next) 214 p = p->next; 215 p->next = s_p; 216 p = s_p; 217 while(p->next) 218 p = p->next; 219 p->next = t_p; 220 } 221 return TRUE; 222 }
main.cpp
1 // 逆波兰运算.cpp : Defines the entry point for the console application. 2 #include "stdafx.h" 3 #include "RP.h" 4 //9+20*(15-4)+7/8-6 5 int main(int argc, char* argv[]) 6 { 7 char exp_sz[128+1] = {0}; 8 char convert_sz[128+1] = {0}; 9 char *p = exp_sz; 10 get_exp(exp_sz); 11 /* 12 while( *p!= '\n'){ 13 puts(p); 14 p += strlen(p); 15 while(*(++p)==NULL); 16 } 17 */ 18 p = convert_exp(exp_sz , convert_sz); 19 printf("%s\n",convert_sz); 20 return 0; 21 }