---恢复内容开始----
养成良好的习惯,看了下别人写的博客,条理清晰,美观,整洁。借鉴下。
问题描述
设表达式有单字母变量和双目四则运算构成,试写一算法,将书写正确的表达式转换为逆波兰表达式。
问题分析
要准确地理解逆波兰式,比如表达式a+b*c-a+b/e的逆波兰式是abc*+a-be/+,根据这一点可以理清算法的思路。输入一个表达式,保存到一个数组中,第一个肯定是操作数,依然在数组中,数组下标为0,然后再遍历下一个,当它为运算符是压入栈中,下一个操作数放在数组下标为1的位置,再判断下一个,为运算符,则与栈中已有的运算符进行比较,如果此运算符级别较大,则将此运算符压入栈,反之,将栈中的运算符先弹出来,让此运算符先入栈,然后再将弹出来的运算符入栈,
---恢复内容结束---
代 码
View Code
1 #include2 #include 3 #define STACK_INIT_SIZE 100 4 #define STACKINCREMENT 10 5 typedef char ElemType; 6 typedef struct{ 7 ElemType *base; 8 ElemType *top; 9 int stacksize; 10 }stack; 11 12 int Initstack(stack &s) 13 { 14 15 s.base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType)); 16 if(!s.base) exit(0); 17 s.top=s.base; 18 s.stacksize=STACK_INIT_SIZE; 19 return 1; 20 } 21 22 int GetTop(stack &s,ElemType &e)//ElemType &e又代表什么意思呢?代表指针,取地址 23 { 24 if(s.top==s.base) 25 return 0; 26 e=*(s.top-1);//明白为什么要先减一 27 return 1; 28 } 29 30 int Push(stack &s,ElemType e) 31 { 32 if(s.top-s.base>=s.stacksize){ 33 s.base=(ElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(ElemType)); 34 if(!s.base) exit(0); 35 s.top=s.base+s.stacksize; 36 s.stacksize+=STACKINCREMENT; 37 } 38 *s.top++=e;//先赋值给s.top然后再将指针加一 39 return 1; 40 } 41 42 int Pop(stack &s,ElemType &e){ 43 if(s.top==s.base) return 0; 44 e=*--s.top; 45 return 1; 46 } 47 bool emptystack(stack &s); 48 bool IsOperator(char c); 49 bool Compare(char c1,char c2); 50 int main() 51 { 52 stack s; 53 Initstack(s); 54 ElemType e; 55 char temp; 56 char a[40]; 57 printf("请输入表达式:"); 58 scanf("%s",a); 59 int i=0,j=0; 60 while(a[i]){ 61 if(!IsOperator(a[i])){//是操作数 62 a[j]=a[i]; 63 i++; 64 j++; 65 } 66 else{//是运算符 67 if(!emptystack(s)) 68 { 69 GetTop(s,e);//得到栈中顶端的运算符 70 if(Compare(e,a[i])){//当下一个运算符的级别高于栈中的运算符时 71 Push(s,a[i]);//直接入栈即可 72 i++; 73 } 74 else//若下一个运算符的级别低于栈中的元素时,将运算符出栈 75 { 76 while(!emptystack(s)) 77 { 78 Pop(s,e); 79 a[j]=e; 80 j++; 81 } 82 } 83 } 84 else{//是第一个运算符,第一个肯定是先入栈的 85 Push(s,a[i]); 86 i++; 87 } 88 } 89 } 90 while(!emptystack(s)) 91 { 92 Pop(s,e); 93 a[j]=e; 94 j++; 95 } 96 printf("%s",a); 97 98 return 1; 99 100 } 101 bool emptystack(stack &s){ 102 if(s.top==s.base) 103 return true; 104 else 105 return false; 106 } 107 bool IsOperator(char c){ 108 switch (c){ 109 110 case '+':return true;break; 111 case'-':return true;break; 112 case'*':return true;break; 113 case'/':return true;break; 114 115 default: 116 return false; 117 break; 118 } 119 } 120 bool Compare(char c1,char c2){ 121 if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/')) 122 return true; 123 else 124 return false; 125 }
总结
说实话,可能这才算真正意义上的编程了,昨晚这代码还没调试成功,朋友就来叫我回去,看到自己思路属于混乱状态,也就没有继续做下去,回去的时候在想,有些基本的知识我并不懂,思路也不是很清晰,想问题会卡在某个地方。这是最重要的问题,学会思考,条理清晰,善于分析。我不得不说,自己以前的学习都是在“伪学习”,没有这些思考,也就尝不到学习的乐趣,相应地也就会把学习作为一种负担,我希望这是一个开始,现在意识到这些问题还不迟,我的学习态度,学习方法应该要有个大的转变。
我得承认写这个代码,让我对栈的基本操作有了更深的认识,并学会运用,刚开始只是知道这么个概念,学以致用,继续加油!