数据结构之简单表达式计算器(读入中缀转后缀,通过后缀计算结果)
2014-04-02 11:15
155 查看
# include <stdio.h> # include <stdlib.h> # include <ctype.h> # include <string.h> typedef struct Node //中缀转后缀表达式使用的结点 { char str; struct Node * pNext; }NODE,* PNODE; typedef struct iNode //后缀表达式使用的结点 { double val; struct iNode * pNext; }INODE,* PINODE; typedef struct stack //中缀转后缀表达式使用的栈 { PNODE pBase; PNODE pTop; }STACK,* PSTACK; typedef struct istack //后缀表达式使用的栈 { PINODE pBase; PINODE pTop; }ISTACK,* PISTACK; //以下为中缀转后缀表达式使用的函数 void init(PSTACK); void push(PSTACK,char); bool pop(PSTACK,char *); bool empty(PSTACK); void traverse(PSTACK); //以下为后缀表达式使用的函数 void initi(PSTACK); void pushi(PSTACK,double); bool popi(PSTACK,double *); bool emptyi(PSTACK); void traversei(PSTACK); char * midtolast(); //读入中缀表达式转后缀表达式使用的函数 void result(char*); //用后缀表达式计算结果 int main() { char * pstr; pstr= midtolast(); strcat(pstr,"#"); result(pstr); return 0; } void init(PSTACK pStack) { pStack->pBase=pStack->pTop=(PNODE)malloc(sizeof(NODE)); pStack->pBase->pNext=NULL; } void push(PSTACK pStack,char str) { PNODE pNew=(PNODE)malloc(sizeof(NODE)); pNew->pNext=pStack->pTop; pNew->str=str; pStack->pTop=pNew; } bool pop(PSTACK pStack,char * pstr) { if (pStack->pTop==pStack->pBase) return false; *pstr=pStack->pTop->str; PNODE pTemp=pStack->pTop; pStack->pTop=pStack->pTop->pNext; free(pTemp); return true; } bool empty(PSTACK pStack ) { if (pStack->pTop==pStack->pBase) return true; return false; } void traverse(PSTACK pStack) { PNODE p=pStack->pTop; while(p!=pStack->pBase) { printf("%c ",p->str); p=p->pNext; } printf("\n"); } void initi(PISTACK pStack) { pStack->pBase=pStack->pTop=(PINODE)malloc(sizeof(INODE)); pStack->pBase->pNext=NULL; } void pushi(PISTACK pStack,double val) { PINODE pNew=(PINODE)malloc(sizeof(INODE)); pNew->pNext=pStack->pTop; pNew->val=val; pStack->pTop=pNew; } bool popi(PISTACK pStack,double * pVal) { if (pStack->pTop==pStack->pBase) return false; *pVal=pStack->pTop->val; PINODE pTemp=pStack->pTop; pStack->pTop=pStack->pTop->pNext; free(pTemp); return true; } bool emptyi(PISTACK pStack ) { if (pStack->pTop==pStack->pBase) return true; return false; } void traversei(PISTACK pStack) { PINODE p=pStack->pTop; while(p!=pStack->pBase) { printf("%f ",p->val); p=p->pNext; } printf("\n"); } char * midtolast() { char ch,str,str1[50]; STACK s; init(&s); printf("请输入算式,用#号结束:"); scanf("%c",&ch); int i=0; while('#'!=ch) { while( ch>='0' && ch<='9') { str1[i++]=ch; //printf("%c",ch); scanf("%c",&ch); if (ch<'0' || ch>'9') { str1[i++]=' '; //printf(" "); break; } } if(')'==ch) { pop(&s,&str); while('('!=str) { str1[i++]=str; str1[i++]=' '; //printf("%c ",str); pop(&s,&str); } } else if ( '+'== ch || '-' == ch ) { if( empty(&s) ) { push(&s,ch); } else { do { pop(&s,&str); if ('('==str) { push(&s,str); break; } str1[i++]=str; str1[i++]=' '; //printf("%c ",str); } while (!empty(&s)); push(&s,ch); } } else if ( '*'== ch || '/' == ch ) { if( empty(&s) ) { push(&s,ch); } else { pop(&s,&str); if ('('==str || '+'== str || '-' == str ) { push(&s,str); push(&s,ch); } else { str1[i++]=str; str1[i++]=' '; //printf("%c ",str); push(&s,ch); } } } else if ( '#'== ch) { break; } else { push(&s,ch); } scanf("%c",&ch); } while(!empty(&s)) { pop(&s,&str); str1[i++]=str; str1[i++]=' '; //printf("%c ",str); } //printf("\n"); str1[i++]='\0'; printf("后缀表达式:%s\n",str1); char * pstr=(char*)malloc(50); strcpy(pstr,str1); return pstr; } void result(char* pstr) { double d,e; ISTACK s; int i=0,j=0; char str[50]; char ch=pstr[j++]; while(ch!='#') { while( isdigit(ch) || ch=='.') { str[i++]=ch; str[i]='\0'; ch=pstr[j++]; if (ch==' ' || ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='#' ) { d=atof(str); pushi(&s,d); i=0; break; } } switch(ch) { case '+': popi(&s,&d); popi(&s,&e); pushi(&s,e+d); break; case '-': popi(&s,&d); popi(&s,&e); pushi(&s,e-d); break; case '*': popi(&s,&d); popi(&s,&e); pushi(&s,e*d); break; case '/': popi(&s,&d); popi(&s,&e); if (d!=0) { pushi(&s,e/d); } else { printf("除零错误!!!\n"); return ; } break; } ch=pstr[j++]; } printf("计算结果:"); traversei(&s); }
相关文章推荐
- [C/C++]反转链表
- 动易2006序列号破解算法公布
- 华为交换机的后缀详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构与算法揭秘二
- C#数据结构揭秘一
- 浅析STL中的常用算法
- JavaScript 组件之旅(二)编码实现和算法
- Linux内核链表实现过程
- 找出链表倒数第n个节点元素的二个方法
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- java数据结构和算法学习之汉诺塔示例
- python基础教程之python消息摘要算法使用示例
- Java数据结构之简单链表的定义与实现方法示例
- qqwry.dat的数据结构图文解释第1/2页
- STL list链表的用法详细解析
- php的hash算法介绍