将中缀表达式转换为后缀表达式C程序

合集下载

将中缀表达式转换为后缀表达式C程序

将中缀表达式转换为后缀表达式C程序

5 将中缀表达式转换为后缀表达式【问题描述】表达式转换。

输入的中缀表达式为字符串,转换得到的后缀表达式存入字符数组中并输出。

例如:a*(x+y)/(b-x) 转换后得:a x y + * b x - /【数据结构】●定义一个暂时存放运算符的转换工作栈opst。

●中缀表达式字符串char *infix;●后缀表达式字符串char *postfix;【算法提示】转换规则:把运算符移到它的两个操作数后面,删除掉所有的括号。

从头到尾扫描中缀表达式,对不同类型的字符按不同情况处理:●数字或小数点,直接写入字符串postfix,并在每个数值后面写入一个空格;●左括号,进栈,直到遇见相配的右括号,才出栈;●右括号,表明已扫描过括号内的中缀表达式,把从栈顶直到对应左括号之间的运算符依次退栈,并把结果推入栈内;●对于运算符,分两种情况处理:◆该运算符的优先级大于栈顶符号的优先级,则入栈;◆若该运算符的优先级小于栈顶优先级,则先弹出栈顶运算符、写入postfix串;继续将该运算符与栈顶运算符比较,直到能把它推入栈内为止(即优先级大于栈顶运算符)。

说明:自行设计运算符优先级的表示。

【主要代码】#include<iostream.h>#include<assert.h>#include<math.h>#include<string.h>const int stackIncreament=0;class opst{public:opst(int sz=50){maxSize=sz;top=-1;elements=new char[maxSize];assert(elements!=NULL);}~opst(){delete[]elements;}bool IsEmpty(){return (top==-1)?true:false;} bool IsFull(){return(top==maxSize-1)?true:false;}void Push( char &x);bool Pop(char &x);bool getTop(char &x);int getSize()const{return top+1;}void MakeEmpty(){top=-1;}void input();void Convert();friend ostream& operator<<(ostream &os,opst &s);private:char *elements;int top;int maxSize;void overflowProcess();};void opst::overflowProcess()//溢出处理{char *newArray=newchar[maxSize+stackIncreament];for(int i=0;i<=top;i++)newArray[i]=elements[i];maxSize=maxSize+stackIncreament; delete [] elements;elements=newArray;}void opst::Push(char &x){if(IsFull()==true) overflowProcess(); elements[++top]=x;}bool opst::Pop( char &x){if(IsEmpty()==true) return false;x=elements[top--];return true;}bool opst::getTop(char &x){if(IsEmpty()==true)return false;x=elements[top];return true;}ostream& operator<<(ostream &os,opst &s) {os<<"top=="<<s.top<<endl;for(int i=0;i<=s.top;i++)os<<s.elements[i];return os;}void opst::input(){char ch[20];cout<<"请输入中缀表达式(括号不能省略):"<<endl;cin.getline(ch,20);int i=0;while(ch[i]!='\0'){this->Push(ch[i]);i++;}ch[i]='#';}bool isdigit(char &x){if((x>='a'&&x<='z')||(x>='A'&&x<='Z')||(x>=' 0'&&x<='9'))return true;else return false;}int isp(char &x)//设置栈内优先级{switch(x){case '#':{return 0;break;}case '(':{return 1;break;}case '*':case '/':case '%':{return 5;break;}case '+':case '-':{return 3;break;}case ')':{return 6;break;}}}int icp(char &x)//设置栈外优先级{switch(x){case '#':{return 0;break;}case '(':{return 6;break;}case '*':case '/':case '%':{return 4;break;}case '+':case '-':{return 2;break;}case ')':{return 1;break;}}}void opst::Convert(){opst s;int i=0;char ch='#',ch1,op;s.Push(ch);this->Push(ch);elements[i];while(this->IsEmpty()==false&&elements[i]! ='#'){if(isdigit(elements[i])){cout<<elements[i];i++;}else{s.getTop(ch1);if(isp(ch1)<icp(elements[i])){s.Push(elements[i]);i++;}else if(isp(ch1)>icp(elements[i])){s.Pop(op);cout<<op;}else{s.Pop(op);if(op=='(') i++;}}}}void main(){opst a;a.input();cout<<"后缀表达式为:"<<endl;a.Convert();cout<<endl;}【实验过程】请输入中缀表达式(括号不能省略):(a+((b-c)/d))后缀表达式为:abc-d/+【实验体会】怎么样设置栈内外的优先级是解决这个程序的关键,我是用了开关语句来实现的。

C++实现中缀表达式转后缀表达式

C++实现中缀表达式转后缀表达式

C++实现中缀表达式转后缀表达式本⽂实例为⼤家分享了C++实现中缀表达式转后缀表达式的具体代码,供⼤家参考,具体内容如下⼀、思路:和中缀表达式的计算类似,只不过不⽤计算,把表达式输出即可1.⽤字符数组存储整⾏输⼊的中缀表达式;2.接着从字符数组的0位置开始判断字符,如果是数字,那就要判断后⾯是否是数字,如果是就不断扫描组成⼀个整数(暂不考虑负数和⼩数),最终组成⼀个整数,然后输出这个数(因为不⽤计算,所以直接输出即可);3.如果是左括号,直接进符号栈;4.如果是操作运算符,与符号栈的栈顶元素⽐较优先级:如果⾼就压⼊栈;低,就取出符号栈顶的元素输出;接着,再判断符号栈顶的元素和当前的运算符号继续⽐较优先级,重复前⾯步骤,直到栈空或者当前的符号优先级⾼;5.如果是右括号,把符号栈栈顶的元素取出,如果不是左括号,把取出的运算符输出,接着取符号栈栈顶的元素,直到符号栈中取出的符号是左括号;6.当扫描完字符数组时,判断符号栈是否为空:不为空,把符号栈栈顶的元素取出,输出到窗⼝,直到符号栈为空。

⼆、实现程序:// 中缀表达式转后缀表达式// 操作符:+、-、*、/、%// 输⼊:可以⽤cin.getline(arr, 250)或者cin.get(ch) && ch != '\n'// 测试数据:输⼊格式:(注意:不能有中⽂的操作符)// 2+(3+4)*5// 16+2*30/4// 输出格式:// 2 3 4 + 5 * +// 16 2 30 * 4 / +#include <iostream>#include <stack>// 判断是否是操作符bool isOperator(char ch) {if(ch == '+' || ch == '-' || ch == '*' || ch == '/')return true;return false; // 否则返回false}// 获取优先级int getPriority(char ch) {int level = 0; // 优先级switch(ch) {case '(':level = 1;break;case '+':case '-':level = 2;break;case '*':case '/':level = 3;break;default:break;}return level;}int main(int argc, const char * argv[]) {// insert code here...int num;char arr[250]; // ⼀个⼀个的读取表达式,直到遇到'\0'std::stack<char> op; // 栈op:存储操作符while(1) {std::cin.getline(arr,250);int len, i;char c; // c存储从栈中取出的操作符len = (int)strlen(arr); // strlen()输出的是:unsigned long类型,所以要强制转换为int类型i = 0;while(i < len) {if(isdigit(arr[i])) { // 如果是数字num = 0;do {num = num * 10 + (arr[i] - '0'); // ch - 48根据ASCAII码,字符与数字之间的转换关系i++; // 下⼀个字符}while(isdigit(arr[i]));std::cout << num << " ";} else if(arr[i] == '(') { // (:左括号op.push(arr[i]);i++;} else if(isOperator(arr[i])) { // 操作符if(op.empty()) {// 如果栈空,直接压⼊栈op.push(arr[i]);i++;}else {// ⽐较栈op顶的操作符与ch的优先级// 如果ch的优先级⾼,则直接压⼊栈// 否则,推出栈中的操作符,直到操作符⼩于ch的优先级,或者遇到(,或者栈已空while(!op.empty()) {c = op.top();if(getPriority(arr[i]) <= getPriority(c)) {// 优先级低或等于std::cout << c << " ";op.pop();} else // ch优先级⾼于栈中操作符break;} // while结束op.push(arr[i]); // 防⽌不断的推出操作符,最后空栈了;或者ch优先级⾼了i++;} // else} else if(arr[i] == ')') { // 如果是右括号,⼀直推出栈中操作符,直到遇到左括号(while(op.top() != '(') {std::cout << op.top() << " ";op.pop();}op.pop(); // 把左括号(推出栈i++;} else // 如果是空⽩符,就进⾏下⼀个字符的处理i++;} // 第⼆个while结束while(!op.empty()) { // 当栈不空,继续输出操作符std::cout << op.top() << " ";op.pop();}std::cout << std::endl;flush(std::cout);} // 第⼀个while结束return 0;}运⾏结果:以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

C语言实现中缀表达式转后缀表达式

C语言实现中缀表达式转后缀表达式

C语⾔实现中缀表达式转后缀表达式代码如下:#include <stdio.h>#include <stdlib.h>#include <ctype.h>#define STACK_INIT_SIZE 20#define STACKINCREMENT 10typedef char ElemType;typedef struct {ElemType *base;ElemType *top;int StackSize;}sqStack;void InitStack(sqStack *s){s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if( !s->base ){exit(0);}s->top = s->base;s->StackSize = STACK_INIT_SIZE;}void push(sqStack *s,ElemType e) {if( s->top - s->base >= s->StackSize){s->base = (ElemType *)realloc(s->base,(s->StackSize+STACKINCREMENT)*sizeof(ElemType));if( !s->base ){exit(0);}}*(s->top) = e;s->top++;}void pop(sqStack *s,ElemType *e){if( s->top == s->base){return;}*e = *--(s->top);}int Stacklen(sqStack s){return (s.top-s.base);}int main(){sqStack s;char c, e;InitStack(&s);printf("请输⼊中缀表达式,以#作为结束标志:");scanf("%c",&c);while( c != '#' ){while ( c>='0' && c<='9' ){printf("%c",c);scanf("%c",&c);if (c<'0'||c>'9'){printf("");}}if ( ')' == c ){pop(&s, &e);while( '(' != e ){printf("%c ",e);pop(&s,&e);}}else if ( '+'==c || '-'==c){if ( !Stacklen(s) ){push(&s,c);}else{do{pop(&s,&e);if ( '('==e ){push(&s,e);}else{printf("%c ",e);}}while( Stacklen(s) && '('!=e ); push(&s,c);}}else if ( '*'==c || '/'==c || '('==c ){push(&s,c);}else if ('#'==c) {break;}else{printf("出错,输⼊格式错误\n");return -1;}scanf("%c",&c);}while( Stacklen(s) ){pop(&s,&e);printf("%c ",e);}return0;}运⾏结果:。

c语言实现中缀,后缀,前缀表达式转换并求值

c语言实现中缀,后缀,前缀表达式转换并求值

c语言实现中缀,后缀,前缀表达式转换并求值c语言实现中缀,后缀,前缀表达式转换并求值九#include #include #define MAXNUM 100 typedef struct Node//定义存储中缀表达式的结点类型{int data; int data1; char data2; struct Node *next; }Lnode; typedef struct Node2//定义存储前缀表达式的结点类型{int data; int data1; char data2; struct Node2 *next; struct Node2 *prior; }Lnode2; typedef int selemtype1;//定义运算数栈的结点typedef struct//定义运算数栈的类型{selemtype1 *base; selemtype1 *top; }sqstack1; void InitStack1(sqstack1 &s)//新建一个空运算数栈{=(selemtype1 *)malloc(MAXNUM*sizeof(selemtype1));=; if(!) printf(“出错:申请空间失败!\\n”); } void Push1(sqstack1 &s,selemtype1 &e)//运算数栈,入栈:插入元素e为新的栈顶元素{ if(>=MAXNUM) printf(“出错:表达式过长!1\\n”); *++ =e; } void GetTop1(sqstack1 s,selemtype1 &e)//运算数栈,用e返回栈顶元素{e=*(); } void Popopnd1(sqstack1 &s,selemtype1 &e) //运算数栈,退栈:删除栈顶元素,并用e返回其值{e=*--; } int stackempy1(sqstack1 s) //运算数栈,若为空栈返回1,否则返回0 {if(==) return 1; else return 0; } typedef char selemtype2;//定义运算符栈的结点类型typedef struct//定义运算符栈类型{selemtype2 *base; selemtype2 *top; }sqstack2; void InitStack2(sqstack2 &s)//新建一个空运算符栈{=(selemtype2 *)malloc(MAXNUM*sizeof(selemtype2)); =; if(!) printf(“出错:申请空间失败!\\n”); } void Push2(sqstack2 &s,selemtype2 &e)//运算符栈,入栈:插入元素e为新的栈顶元素{ if(>=MAXNUM) printf(“出错:表达式过长!2\\n”); *++ =e; } void GetTop2(sqstack2 s,selemtype2 &e)//运算符栈,用e返回栈顶元素{e=*(); } void Popopnd2(sqstack2 &s,selemtype2 &e) //运算符栈,退栈:删除栈顶元素,并用e返回其值{e=*--; } int stackempy2(sqstack2 s) //运算符栈,若为空栈返回1,否则返回0 {if(==) return 1; else return 0; } void priority(char c,int &i)//确定运算符优先级{if (c==‘*’||c==‘/’||c==‘%’) i=2 ; else if (c==‘+’||c==‘-’) i=1 ; else i=0; } int compare(char a,char b)//比较栈顶元素运算符与外部运算符优先级大小,外部优先级大则返回1,反之返回0 {int in,out; priority(a,in); priority(b,out); if(out>in) return 1; else return 0; } void Operat(sqstack1 &OPND,sqstack2&OPTR) {int num1,num2,num; char c; Popopnd1(OPND,num2);Popopnd1(OPND,num1);Popopnd2(OPTR,c); switch(c) {case ‘+’:num=num1+num2;break; case ‘-’:num=num1-num2;break; case ‘*’:num=num1*num2;break; case ‘/’:num=num1/num2;break; case ‘%’:num=num1%num2;break; } Push1(OPND,num); } void Operatqianzhui(sqstack1 &OPND,sqstack2 &OPTR) {int num1,num2,num; char c; Popopnd1(OPND,num1);Popopnd1(OPND,num2);Popopnd2(OPTR,c); switch(c) {case ‘+’:num=num1+num2;break; case ‘-’:num=num1-num2;break; case ‘*’:num=num1*num2;break; case ‘/’:num=num1/num2;break; case ‘%’:num=num1%num2;break; } Push1(OPND,num); }voidhouzhuiqiuzhi(Lnode *p,int &e) {sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; char c; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(p) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; Push2(OPTR,c); Operat(OPND,OPTR); break; default:printf(“结点有误”); brea k; } p=p->next; } Popopnd1(OPND,n); e=n; } void zhongzhui(Lnode *p) {sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; //后缀表达式求值//中缀表达式求值char c,c2; Lnode *first; first=p; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(!stackempy2(OPTR)||p) {while(p) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { switch(c){case ‘(‘: Push2(OPTR,c);break; case ‘)’: GetTop2(OPTR,c2); while(c2!=‘(‘) {Operat(OPND,OPTR);GetTop2(OPTR,c2);}Popopnd2(OPTR,c2); break; default: GetTop2(OPTR,c2);if(compare(c2,c)) Push2(OPTR,c); else { Operat(OPND,OPTR); Push2(OPTR,c); } break; } } break; default: printf(“结点有误”); break; } p=p->next; } while(!stackempy2(OPTR))Operat(OPND,OPTR); } Popopnd1(OPND,n); p=first->next; while(p) {if(p->data==1) printf(“%d “,p->data1); if(p->data==2) printf(“%c”,p->data2);p=p->next; } printf(“=%d “,n); }void houzhui(Lnode *p)//中缀表达式转化为后缀表达式{sqstack2OPTR; //运算符栈Lnode *r,*q,*head; int n; char c,c2; InitStack2(OPTR); p=p->next;q=(Lnode*)malloc(sizeof(struct Node)); head=q; while(p) { switch(p->data) {case 1:n=p->data1; r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=1; q->data1=n; break; case 2:c=p->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { switch(c) { case ‘(‘: Push2(OPTR,c);break; case ‘)’: Popopnd2(OPTR,c2); while(c2!=‘(‘) { r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; Popopnd2(OPTR,c2); } break; default: GetTop2(OPTR,c2); while(!compare(c2,c)){ Popopnd2(OPTR,c2); r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; GetTop2(OPTR,c2); }Push2(OPTR,c); break; } } break; default: printf(“结点有误”); break; } p=p->next; } while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2); r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; } q->next=NULL; q=head->next; while(q) {if(q->data==1) printf(“%d “,q->data1); if(q->data==2) printf(“%c”,q->data2); q=q->next; } houzhuiqiuzhi(head,n); printf(“=%d “,n); } void qianzhuiqiuzhi(Lnode2 *p,int &e) //前缀表达式求值{sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; char c; Lnode2 *head; head=p; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(p!=head) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; Push2(OPTR,c);Operatqianzhui(OPND,OPTR); break; default:printf(“结点有误”); break; } p=p->next; } Popopnd1(OPND,n); e=n; }void qianzhui(Lnode *p)式{sqstack2 OPTR; //运算符栈InitStack2(OPTR); int n; char c,c2; Lnode *first; Lnode2 *q,*head,*r,*head2,*s; first=p; p=p->next; q=(Lnode2*)malloc(sizeof(struct Node2)); //中缀表达式转化为前缀表达//建立存中缀表达式的双向循环链表head=q; while(p) {r=(Lnode2*)malloc(sizeof(struct Node2)); q->next=r; r->prior=q; q=q->next; q->data=p->data; q->data1=p->data1; q->data2=p->data2; p=p->next; } q->next=head; head->prior=q; s=(Lnode2*)malloc(sizeof(struct Node2)); //建立存前缀表达式的双向循环链表head2=s; while(q!=head) {switch(q->data) {case 1:n=q->data1; r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=1; s->data1=n; break; case 2:c=q->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { GetTop2(OPTR,c2); if(c2==‘)’) Push2(OPTR,c); else{ switch(c) { case ‘)’:Push2(OPTR,c);break; case ‘(‘: Popopnd2(OPTR,c2); while(c2!=‘)’) { r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; Popopnd2(OPTR,c2); } break; default: GetTop2(OPTR,c2); while(!compare(c2,c)){ Popopnd2(OPTR,c2); r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; GetTop2(OPTR,c2); } Push2(OPTR,c); break; } } } break; default:printf(“结点有误”); break; }q=q->prior; } while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2); r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; } s->next=head2; head2->prior=s; while(s!=head2) {if(s->data==1) printf(“%d “,s->data1);if(s->data==2) printf(“%c”,s->data2); s=s->prior; } qianzhuiqiuzhi(head2,n); printf(“=%d “,n);}int main() { char n[10]; char c; int i,j,k,a,b,z,y,e; Lnode *p,*q,*first; i=0;e=1;a=0;b=1;z=0;y=0;p=(Lnode*)malloc(sizeof(struct Node)); first=p; printf(“请输入中缀表达式”); do { c = getchar(); if(‘0’{ switch (c) { case ‘+’: case ‘-’: case ‘*’: case ‘/’: case ‘%’: case ‘(‘:case ‘)’: case ‘\\n’: { if(n[0]>‘0’&&n[0]next=q; p=p->next; for(k=0;k{ for(j=0;j a=a+(n[k]-’0’)*e; e=1; n[k]=‘0’; } p->data=1; p->data1=a; i=0;a=0; } if(c!=‘\\n’) { if(p->data==2) { if(p->data2!=‘)’&&c!=‘(‘) b=0; } q=(Lnode*)malloc(sizeof(struct Node)); p->next=q; p=p->next; p->data=2; p->data2=c; if(c==‘(‘) z++; if(c==‘)’) y++; } } default: if(c!=‘+’&&c!=‘-’&&c!=‘*’&&c!=‘/’&& c!=‘%’&&c!=‘\\n’&&c!=‘(‘&&c!=‘)’)b=0; } } }while (c != ‘\\n’); if(z!=y) b=0; p->next=NULL; if(b==0) printf(“输入中缀表达式有误”); else {printf(“输入1中缀表达式求值,输入2后缀表达式求值,输入3前缀表达式求值”); scanf(“%d”,&b); if(b==1) zhongzhui(first); if(b==2) houzhui(first); if(b==3) qianzhui(first); } return 1; }。

中缀表达式转换为后缀表达式C语言程序

中缀表达式转换为后缀表达式C语言程序

#ifndef STACK_H#define STACK_H#include<stdio.h>#include<stdlib.h>typedef struct astack *Stack;typedef struct astack{int top;int maxtop;char* data;}Astack;Stack NewEmpty(int size){Stack S=(Stack)malloc(sizeof(Astack));S->maxtop=size;S->top=-1;S->data=(char*)malloc(size*sizeof(char)); return S;}int StackEmpty(Stack S){return S->top<0;}int StackFull(Stack S){return S->top==S->maxtop;}int Peek(Stack S){return S->data[S->top];}void Push(char x,Stack S){if(StackFull(S)){printf("Stack is full!\n");exit(1);}elseS->data[++S->top]=x;int Pop(Stack S){if(StackEmpty(S)){printf("Stack is empty!\n");exit(1);}elsereturn S->data[S->top--];}Stack NewStack(int size){Stack S=NewEmpty(size);int i,x,num;printf("Please enter the number of data:\n"); scanf("%d",&num);for(i=0;i<num;i++){printf("Please enter the %d date:\n",i+1); scanf("%c",&x);Push(x,S);}return S;}void ShowStack(Stack S){int i;for(i=0;i<=S->top;i++){printf(" %c",S->data[i]);}printf("\n");}#endif#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include"1.h"#define MAX 30int Precedence(char ch){if(ch=='+'||ch=='-')return 2; else if(ch=='*'||ch=='/')return 3; else if(ch=='('||ch==')')return 4; else if(ch=='@')return 1;else return 0;}void Change(char *s1,char *s2) {Stack S=NewEmpty(MAX); int i=0,j=0,one=0;char ch=s1[i];Push('@',S);while(ch!='@'){if(ch==' ')ch=s1[++i];else if(isalnum(ch)!=0){if(one==1){s2[j++]=' ';}s2[j++]=ch;ch=s1[++i];one=0;}else if(ch=='('){Push(ch,S);ch=s1[++i];one=1;}else if(ch==')'){while(Peek(S)!='(')s2[j++]=Pop(S);Pop(S);ch=s1[++i];one=1;}else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){while(Peek(S)!='('&&Precedence(Peek(S))>=Precedence(ch)) {s2[j++]=Pop(S);one=1;}Push(ch,S);ch=s1[++i];one=1;}}while(StackEmpty(S)!=1){s2[j++]=Pop(S);one=1;}s2[j]='\0';}int main(){char s1[MAX],s2[MAX];printf("Enter the equation:\n");gets(s1);Change(s1,s2);printf("%s\n",s2);return 0;}。

C语言实现中缀表达式转换为后缀表达式

C语言实现中缀表达式转换为后缀表达式

C语⾔实现中缀表达式转换为后缀表达式本⽂实例为⼤家分享了C语⾔实现中缀表达式转后缀表达式的具体代码,供⼤家参考,具体内容如下中缀表达式转换为后缀表达式(思路)1.创建栈2.从左向右顺序获取中缀表达式a.数字直接输出b.运算符情况⼀:遇到左括号直接⼊栈,遇到右括号将栈中左括号之后⼊栈的运算符全部弹栈输出,同时左括号出栈但是不输出。

情况⼆:遇到乘号和除号直接⼊栈,直到遇到优先级⽐它更低的运算符,依次弹栈。

情况三:遇到加号和减号,如果此时栈空,则直接⼊栈,否则,将栈中优先级⾼的运算符依次弹栈(注意:加号和减号属于同⼀个优先级,所以也依次弹栈)直到栈空或则遇到左括号为⽌,停⽌弹栈。

(因为左括号要匹配右括号时才弹出)。

情况四:获取完后,将栈中剩余的运算符号依次弹栈输出例:⽐如将:2*(9+6/3-5)+4转化为后缀表达式 2 9 6 3 / +5 - * 4 +转换算法代码如下:/*中缀转后缀函数*/void Change(SqStack *S,Elemtype str[]){int i=0;Elemtype e;InitStack(S);while(str[i]!='\0'){while(isdigit(str[i])){/*过滤数字字符,直接输出,直到下⼀位不是数字字符打印空格跳出循环 */printf("%c",str[i++]);if(!isdigit(str[i])){printf(" ");}}/*加减运算符优先级最低,如果栈顶元素为空则直接⼊栈,否则将栈中存储的运算符全部弹栈,如果遇到左括号则停⽌,将弹出的左括号从新压栈,因为左括号要和⼜括号匹配时弹出,这个后⾯单独讨论。

弹出后将优先级低的运算符压⼊栈中*/ if(str[i]=='+'||str[i]=='-'){if(!StackLength(S)){PushStack(S,str[i]);}else{do{PopStack(S,&e);if(e=='('){PushStack(S,e);}else{printf("%c ",e);}}while( StackLength(S) && e != '(' );PushStack(S,str[i]);}}/*当遇到右括号是,把括号⾥剩余的运算符弹出,直到匹配到左括号为⽌左括号只弹出不打印(右括号也不压栈)*/else if(str[i]==')'){PopStack(S,&e);while(e!='('){printf("%c ",e);PopStack(S,&e);}}/*乘、除、左括号都是优先级⾼的,直接压栈*/else if(str[i]=='*'||str[i]=='/'||str[i]=='('){PushStack(S,str[i]);}else if(str[i]=='\0'){break;}else{printf("\n输⼊格式错误!\n");return ;}i++;}/*最后把栈中剩余的运算符依次弹栈打印*/while(StackLength(S)){PopStack(S,&e);printf("%c ",e);}}完整代码如下:#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<assert.h>#define INITSIZE 20#define INCREMENT 10#define MAXBUFFER 20#define LEN sizeof(Elemtype)/*栈的动态分配存储结构*/typedef char Elemtype;typedef struct{Elemtype *base;Elemtype *top;int StackSize;}SqStack;/*初始化栈*/void InitStack(SqStack *S){S->base=(Elemtype*)malloc(LEN*INITSIZE);assert(S->base !=NULL);S->top=S->base;S->StackSize=INITSIZE;}/*压栈操作*/void PushStack(SqStack *S,Elemtype c){if(S->top - S->base >= S->StackSize){S->base=(Elemtype*)realloc(S->base,LEN*(S->StackSize+INCREMENT));assert(S->base !=NULL);S->top =S->base+S->StackSize;S->StackSize+=INCREMENT;}*S->top++ = c;}/*求栈长*/int StackLength(SqStack *S){return (S->top - S->base);}/*弹栈操作*/int PopStack(SqStack *S,Elemtype *c){if(!StackLength(S)){return 0;}*c=*--S->top;return 1;}/*中缀转后缀函数*/void Change(SqStack *S,Elemtype str[]){int i=0;Elemtype e;InitStack(S);while(str[i]!='\0'){while(isdigit(str[i])){/*过滤数字字符,直接输出,直到下⼀位不是数字字符打印空格跳出循环 */printf("%c",str[i++]);if(!isdigit(str[i])){printf(" ");}}/*加减运算符优先级最低,如果栈顶元素为空则直接⼊栈,否则将栈中存储的运算符全部弹栈,如果遇到左括号则停⽌,将弹出的左括号从新压栈,因为左括号要和⼜括号匹配时弹出,这个后⾯单独讨论。

用C语言写解释器(三)——中缀转后缀

用C语言写解释器(三)——中缀转后缀

用C语言写解释器(三)——中缀转后缀用C语言写解释器(三)——中缀转后缀分类:用C语言写解释器算法讨论拍拍脑袋 2009-11-01 22:25 4983人阅读评论(4) 收藏举报语言ctokennulllist数据结构声明为提高教学质量,我所在的学院正在筹划编写C语言教材。

《用C语言写解释器》系列文章经整理后将收入书中“综合实验”一章。

因此该系列的文章主要阅读对象定为刚学完C语言的学生(不要求有数据结构等其他知识),所以行文比较罗嗦,请勿见怪。

本人水平有限,如有描述不恰当或错误之处请不吝赐教!特此声明。

操作符排序如果你忘记了后缀表达式的概念,赶紧翻回上一篇《用C语言写解释器(二)》回顾一下。

简单地说,将中缀表达式转换成后缀表达式,就是将操作符的执行顺序由“优先级顺序”转换成“在表达式中的先后顺序”。

因此,所谓的中缀转后缀,其实就是给原表达式中的操作符排序。

比如将中缀表达式 5 * ((10 - 1) / 3) 转换成后缀表达式为 5 10 1 - 3 / *。

其中数字 5 10 1 3 仍然按照原先的顺序排列,而操作符的顺序变为 - / ×,这意味着减号最先计算、其次是除号、最后才是乘号。

也许你还在担心如何将操作符从两个操作数的中间移到它们的后边。

其实不用担心,在完成了排序工作后你就发现它已经跑到操作数的后面了 ^_^。

从中缀表达式1+2×3+4 中逐个获取操作符,依次是+ × +。

如果当前操作符的优先级不大于前面的操作符时,前面操作符就要先输出。

比如例子中的第二个加号,它前面是乘号,因此乘号从这个队伍中跑到输出的队伍中当了“老大”;此时第二个加号再前面的加号比较,仍然没有比它大,因此第一个加号也排到新队伍中去了;最后队伍中只剩下加号自己了,所以它也走了。

得到新队伍里的顺序× + + 就是所求解。

下面的表格中详细展示每一个步骤。

序号输入临时空间输出1 +2 ×+3 + + ×4 + × +5 + + ×6 + × +7 × + +相信你心里还是牵挂着那些操作数。

中缀表达式转后缀表达式 c++代码

中缀表达式转后缀表达式 c++代码

中缀表达式转后缀表达式 c++代码中缀表达式转后缀表达式是一种常见运算表达式的转换方式,该转换方式可以使得运算表达式更加方便和高效。

在转换过程中,我们首先需要了解什么是中缀表达式,什么是后缀表达式以及它们之间的相互转换关系。

中缀表达式是指运算符放在两个运算对象的中间的表达式,例如:A + B * C,其中“+”是运算符,A、B和C是运算对象。

后缀表达式则是指运算符放在两个运算对象的后面的表达式,例如:A B C * +,其中“+”是运算符,A、B和C是运算对象。

中缀表达式和后缀表达式是等价的,它们可以相互转换而不改变表达式的含义。

在C++中,可以使用栈来实现中缀表达式转换为后缀表达式的操作。

具体实现方式如下:1. 遍历中缀表达式中的每个字符和运算符,依次进行如下操作:2. 如果遇到数字或者变量,直接输出到输出队列中。

3. 如果遇到运算符,则将其入栈。

4. 如果遇到“(”符号,则将其入栈。

5. 如果遇到“)”符号,则将栈中的运算符依次弹出并输出到输出队列中,直到遇到左括号为止。

6. 遍历完成后,如果栈中还有运算符,则将其依次弹出并输出到输出队列中。

7. 输出队列中的字符串即为后缀表达式。

下面是一个C++的实现代码示例:#include<iostream>#include<cstring>#include<stack>#include<queue>using namespace std;//将中缀表达式转换为后缀表达式string infixToPostfix(string infix_expression){stack<char> s;queue<char> q;string postfix_expression = "";int len = infix_expression.size();for(int i = 0;i < len;++i){if(infix_expression[i] == '+' || infix_expression[i] == '-' || infix_expression[i] == '*' || infix_expression[i] == '/'){//遇到操作符while(!s.empty() && s.top() != '('){if((infix_expression[i] == '*' || infix_expression[i] == '/') && (s.top() == '+' || s.top() == '-')){break;}q.push(s.top());s.pop();}s.push(infix_expression[i]);}else if(infix_expression[i] == '('){s.push(infix_expression[i]);}else if(infix_expression[i] == ')'){while(!s.empty() && s.top() != '('){q.push(s.top());s.pop();}s.pop();}else if((infix_expression[i] >= '0' && infix_expression[i] <= '9') || (infix_expression[i] >= 'a' && infix_expression[i] <= 'z')){ //遇到数字或变量q.push(infix_expression[i]);}}while(!s.empty()){q.push(s.top());s.pop();}while(!q.empty()){postfix_expression += q.front();q.pop();}return postfix_expression;}int main(){string infix_expression = "a+b*c-(d/e+f)*g";string postfix_expression = infixToPostfix(infix_expression);cout << postfix_expression << endl;return 0;}在代码实现中,我们用一个栈来保存运算符,用一个队列来保存输出的字符。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

5 将中缀表达式转换为后缀表达式
【问题描述】表达式转换。

输入的中缀表达式为字符串,转换得到的后缀表达式存入字符数组中并输出。

例如:a*(x+y)/(b-x) 转换后得:a x y + * b x - /
【数据结构】
●定义一个暂时存放运算符的转换工作栈opst。

●中缀表达式字符串char *infix;
●后缀表达式字符串char *postfix;
【算法提示】转换规则:把运算符移到它的两个操作数后面,删除掉所有的括号。

从头到尾扫描中缀表达式,对不同类型的字符按不同情况处理:
●数字或小数点,直接写入字符串postfix,并在每个数值后面写入一个空格;
●左括号,进栈,直到遇见相配的右括号,才出栈;
●右括号,表明已扫描过括号内的中缀表达式,把从栈顶直到对应左括号之间的运算
符依次退栈,并把结果推入栈内;
●对于运算符,分两种情况处理:
◆该运算符的优先级大于栈顶符号的优先级,则入栈;
◆若该运算符的优先级小于栈顶优先级,则先弹出栈顶运算符、写入postfix串;继续将该
运算符与栈顶运算符比较,直到能把它推入栈内为止(即优先级大于栈顶运算符)。

说明:自行设计运算符优先级的表示。

【主要代码】
#include<iostream.h>
#include<assert.h>
#include<math.h>
#include<string.h>
const int stackIncreament=0;
class opst
{
public:
opst(int sz=50)
{
maxSize=sz;
top=-1;
elements=new char[maxSize];
assert(elements!=NULL);
}
~opst(){delete[]elements;}
bool IsEmpty(){return (top==-1)?true:false;} bool IsFull(){return
(top==maxSize-1)?true:false;}
void Push( char &x);
bool Pop(char &x);
bool getTop(char &x);
int getSize()const{return top+1;}
void MakeEmpty(){top=-1;}
void input();
void Convert();
friend ostream& operator<<(ostream &os,opst &s);
private:
char *elements;
int top;
int maxSize;
void overflowProcess();
};
void opst::overflowProcess()//溢出处理{
char *newArray=new
char[maxSize+stackIncreament];
for(int i=0;i<=top;i++)
newArray[i]=elements[i];
maxSize=maxSize+stackIncreament; delete [] elements;
elements=newArray;
}
void opst::Push(char &x)
{
if(IsFull()==true) overflowProcess(); elements[++top]=x;
}
bool opst::Pop( char &x)
{
if(IsEmpty()==true) return false;
x=elements[top--];
return true;
}
bool opst::getTop(char &x)
{
if(IsEmpty()==true)return false;
x=elements[top];
return true;
}
ostream& operator<<(ostream &os,opst &s) {
os<<"top=="<<s.top<<endl;
for(int i=0;i<=s.top;i++)
os<<s.elements[i];
return os;
}
void opst::input()
{
char ch[20];
cout<<"请输入中缀表达式(括号不能省略):"<<endl;
cin.getline(ch,20);
int i=0;
while(ch[i]!='\0')
{this->Push(ch[i]);i++;}
ch[i]='#';
}
bool isdigit(char &x)
{
if((x>='a'&&x<='z')||(x>='A'&&x<='Z')||(x>=' 0'&&x<='9'))
return true;
else return false;
}
int isp(char &x)//设置栈内优先级
{
switch(x)
{
case '#':
{return 0;break;}
case '(':
{return 1;break;}
case '*':
case '/':
case '%':
{return 5;break;}
case '+':
case '-':
{return 3;break;}
case ')':
{return 6;break;}
}
}
int icp(char &x)//设置栈外优先级{
switch(x)
{
case '#':
{return 0;break;}
case '(':
{return 6;break;}
case '*':
case '/':
case '%':
{return 4;break;}
case '+':
case '-':
{return 2;break;}
case ')':
{return 1;break;}
}
}
void opst::Convert()
{
opst s;
int i=0;
char ch='#',ch1,op;
s.Push(ch);
this->Push(ch);
elements[i];
while(this->IsEmpty()==false&&elements[i]! ='#')
{
if(isdigit(elements[i]))
{
cout<<elements[i];
i++;
}
else
{
s.getTop(ch1);
if(isp(ch1)<icp(elements[i]))
{s.Push(elements[i]);i++;}
else if(isp(ch1)>icp(elements[i]))
{s.Pop(op);cout<<op;}
else
{
s.Pop(op);
if(op=='(') i++;
}
}
}
}
void main()
{
opst a;
a.input();
cout<<"后缀表达式为:"<<endl;
a.Convert();
cout<<endl;
}
【实验过程】
请输入中缀表达式(括号不能省略):
(a+((b-c)/d))
后缀表达式为:
abc-d/+
【实验体会】
怎么样设置栈内外的优先级是解决这个程序的关键,我是用了开关语句来实现的。

具体的转换算法,书上有。

仿照书上的实现,编写了Convert()函数。

这个程序编写起来比较顺利,编写过程中没有遇到什么非常大的问题。

最值得注意的是栈内优先级和栈外优先级的函数,我并没有在类内定义,我是在类外定义的。

所以调用的时候并不用某个对象来调用,而是直接在调用。

这就要注意成员函数和常规函数的区别。

相关文档
最新文档