資料結構中用棧實現表示式求值(c語言實現)
阿新 • • 發佈:2019-01-01
/*
該程式完成了個位數的各類表示式求值
運用了資料結構中的棧及對棧操作的各類函式,操作全用指標完成
如輸入 2+3*(3+3*1)# 輸出結果為 20
經測試個位數的表示式運算結果均正確
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STACK_INIT_SIZE 1000
typedef struct //建造一個空棧
{
char *base;
char *top;
int stacksize;
}SqStack;
int InitStack(SqStack *s) //給棧分配空間,初始化棧
{
(*s).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
if(!((*s).base))
exit(0);
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return 1;
}
int Push(SqStack *s,char *ch) //把接收到的第一個元素壓入棧
{
if(s->top-s->base>=STACK_INIT_SIZE)
return 0;
*((*s).top)=*ch;
(*s).top++;
return 1;
}
void Pop(SqStack *s,char *ch){ //刪除棧頂元素
s->top--;
*ch=*(s->top);
}
char* Gettop(SqStack *s) //得到棧頂元素
{
if(s->top!=s->base)
return (*s).top-1;
}
int In(char *c) //判斷吸收的資料是不是字元
{
switch(*c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':return 1;
default:return 0;
}
}
char *Operate(char *a,char *theta,char *b) //彈出棧的元素進行運算
{
char *c;
*a=*a-48;
*b=*b-48;
c=(char *)malloc(sizeof(char));
switch(*theta)
{
case'+':
*c=*a+*b+48;
break;
case'-':
*c=*a-*b+48;
break;
case'*':
*c=(*a)*(*b)+48;
break;
case'/':*c=(*a)/(*b)+48;break;
}
return c;
}
char Precede(char *ch1,char *ch2) //判斷運算子的先後順序
{
if(*ch1=='+')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='-')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='*')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='/')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='(')
{
if(*ch2=='+')return '<';
if(*ch2=='-')return '<';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '=';
}
if(*ch1==')')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='#')
{
if(*ch2=='+')return '<';
if(*ch2=='-')return '<';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2=='#')return '=';
}
}
int main()
{
char *theta,*ch,*x,*c;
char *a,*b;
SqStack OPND;
SqStack OPTR;
InitStack(&OPND); //創作一個存數字的棧
InitStack(&OPTR); //創作一個存運算子和括號的棧
c=(char *)malloc(sizeof(char)); //分配記憶體
ch=(char *)malloc(sizeof(char));
x=(char *)malloc(sizeof(char));
theta=(char *)malloc(sizeof(char));
a=(char *)malloc(sizeof(char));
b=(char *)malloc(sizeof(char));
*c='#';
Push(&OPTR,c);
printf("請輸入以#結尾的表示式\n");
*ch=getchar();
while((*ch)!='#'||(*(Gettop(&OPTR)))!='#'){ //運算結束停止條件
if(!In(ch)){
Push(&OPND,ch);
printf("壓入OPND棧 %d\n",*ch);
*ch=getchar();
}
else
switch(Precede(Gettop(&OPTR),ch)) //通過比較接收的字元來進行運算
{
case'<':
Push(&OPTR,ch);
printf("壓入OPTR棧 %c\n",*ch);
*ch=getchar();
break;
case'>':
Pop(&OPTR,theta);
printf("壓入前%d %d\n",*b,*a);
Pop(&OPND,b);
Pop(&OPND,a);
printf("刪除後OPND的頭%d %d\n",*b,*a);
Push(&OPND,Operate(a,theta,b));
printf("運算後 %d\n",*theta);
break;
case'=':
Pop(&OPTR,x);
*ch=getchar();
break;}
}
printf("\n\n\n");
printf("運算結果= %d",(*Gettop(&OPND)-48));
}
該程式完成了個位數的各類表示式求值
運用了資料結構中的棧及對棧操作的各類函式,操作全用指標完成
如輸入 2+3*(3+3*1)# 輸出結果為 20
經測試個位數的表示式運算結果均正確
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STACK_INIT_SIZE 1000
typedef struct //建造一個空棧
{
char *base;
char *top;
int stacksize;
}SqStack;
int InitStack(SqStack *s) //給棧分配空間,初始化棧
{
(*s).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
if(!((*s).base))
exit(0);
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return 1;
}
int Push(SqStack *s,char *ch) //把接收到的第一個元素壓入棧
{
if(s->top-s->base>=STACK_INIT_SIZE)
return 0;
*((*s).top)=*ch;
(*s).top++;
return 1;
}
void Pop(SqStack *s,char *ch){ //刪除棧頂元素
s->top--;
*ch=*(s->top);
}
char* Gettop(SqStack *s) //得到棧頂元素
{
if(s->top!=s->base)
return (*s).top-1;
}
int In(char *c) //判斷吸收的資料是不是字元
{
switch(*c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':return 1;
default:return 0;
}
}
char *Operate(char *a,char *theta,char *b) //彈出棧的元素進行運算
{
char *c;
*a=*a-48;
*b=*b-48;
c=(char *)malloc(sizeof(char));
switch(*theta)
{
case'+':
*c=*a+*b+48;
break;
case'-':
*c=*a-*b+48;
break;
case'*':
*c=(*a)*(*b)+48;
break;
case'/':*c=(*a)/(*b)+48;break;
}
return c;
}
char Precede(char *ch1,char *ch2) //判斷運算子的先後順序
{
if(*ch1=='+')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='-')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='*')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='/')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2=='(')return '<';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='(')
{
if(*ch2=='+')return '<';
if(*ch2=='-')return '<';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2==')')return '=';
}
if(*ch1==')')
{
if(*ch2=='+')return '>';
if(*ch2=='-')return '>';
if(*ch2=='*')return '>';
if(*ch2=='/')return '>';
if(*ch2==')')return '>';
if(*ch2=='#')return '>';
}
if(*ch1=='#')
{
if(*ch2=='+')return '<';
if(*ch2=='-')return '<';
if(*ch2=='*')return '<';
if(*ch2=='/')return '<';
if(*ch2=='(')return '<';
if(*ch2=='#')return '=';
}
}
int main()
{
char *theta,*ch,*x,*c;
char *a,*b;
SqStack OPND;
SqStack OPTR;
InitStack(&OPND); //創作一個存數字的棧
InitStack(&OPTR); //創作一個存運算子和括號的棧
c=(char *)malloc(sizeof(char)); //分配記憶體
ch=(char *)malloc(sizeof(char));
x=(char *)malloc(sizeof(char));
theta=(char *)malloc(sizeof(char));
a=(char *)malloc(sizeof(char));
b=(char *)malloc(sizeof(char));
*c='#';
Push(&OPTR,c);
printf("請輸入以#結尾的表示式\n");
*ch=getchar();
while((*ch)!='#'||(*(Gettop(&OPTR)))!='#'){ //運算結束停止條件
if(!In(ch)){
Push(&OPND,ch);
printf("壓入OPND棧 %d\n",*ch);
*ch=getchar();
}
else
switch(Precede(Gettop(&OPTR),ch)) //通過比較接收的字元來進行運算
{
case'<':
Push(&OPTR,ch);
printf("壓入OPTR棧 %c\n",*ch);
*ch=getchar();
break;
case'>':
Pop(&OPTR,theta);
printf("壓入前%d %d\n",*b,*a);
Pop(&OPND,b);
Pop(&OPND,a);
printf("刪除後OPND的頭%d %d\n",*b,*a);
Push(&OPND,Operate(a,theta,b));
printf("運算後 %d\n",*theta);
break;
case'=':
Pop(&OPTR,x);
*ch=getchar();
break;}
}
printf("\n\n\n");
printf("運算結果= %d",(*Gettop(&OPND)-48));
}