資料結構--棧的應用
阿新 • • 發佈:2021-01-13
中綴轉字首、中綴轉字尾、中綴求值
- Stack.h
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
typedef struct Stack{
ElemType data;
struct Stack *next;
}Stack,*StackPtr;
//初始化棧
void InitStack(StackPtr &S)
{
S=NULL;
}
//判空
bool StackEmpty(StackPtr S)
{
if(S==NULL)
return true;
return false;
}
//入棧
void Push(StackPtr &S,ElemType e)
{
StackPtr s=(StackPtr)malloc(sizeof(ElemType));
if(!s)
return ;
s->data=e;
s->next=S;
S=s;
}
//出棧
void Pop(StackPtr &S,ElemType &e)
{
if(StackEmpty(S))
return ;
StackPtr s;
e=S->data;
s=S;
S=S->next;
free (s);
}
//獲得棧頂元素
ElemType GetTop(StackPtr S)
{
if(StackEmpty(S))
return 0;
int e=S->data;
return e;
}
#include<stdio.h>
#include<string.h>
#include"Stack.h"
/*-------------------------
|中綴表示式 轉 字首表示式|
-------------------------*/
void infix_to_prefix(char str[]) {
int i;
char e;
StackPtr OPTR,Result;
InitStack(OPTR);
InitStack(Result);
for (i=strlen(str)-1; i>=0; --i) { //從右到左掃描中綴表示式
if ('0' <= str[i] && str[i] <= '9') { //運算元 入Result棧
Push(Result,str[i]);
}
else if (str[i]=='(') {
while (GetTop(OPTR)!=')') {//依次出站入Result棧
Pop(OPTR,e);
Push(Result,e);
}
Pop(OPTR,e); //右括號出棧
}
else if (str[i]=='+' || str[i]=='-') {//算符優先順序小於棧頂
while (GetTop(OPTR)=='*' || GetTop(OPTR)=='/') {
Pop(OPTR,e);
Push(Result,e);
}
Push(OPTR,str[i]);//將'+'或'-'入棧
}
else {//其他情況入棧
Push(OPTR,str[i]);
}
}
// 將剩餘運算元入Result棧
while (!StackEmpty(OPTR)) {
Pop(OPTR,e);
Push(Result,e);
}
//輸出
printf("\n字首表示式:");
while(!StackEmpty(Result))
{
Pop(Result,e);
printf("%c",e);
}
}
/*-------------------------
|中綴表示式 轉 字尾表示式|
-------------------------*/
void infix_to_suffix(char str[]) {
int i, j;
char e;
StackPtr OPTR;
InitStack(OPTR);
printf("\n字尾表示式:");
for (i=0; str[i]!='\0';i++) { //遍歷
// 是數字
if ('0' <= str[i] && str[i] <= '9') {
printf("%c",str[i]);//輸出
}
// 是符號
else if (str[i]=='+'|| str[i]=='-') { //算符優先順序小於棧頂
if(GetTop(OPTR)=='*' || GetTop(OPTR)=='/')
{
Pop(OPTR,e);
printf("%c",e); //出棧,輸出
}
Push(OPTR,str[i]);//將'+'或'-'入棧
}
else if(str[i]==')')
{
while(GetTop(OPTR)!='(')
{
Pop(OPTR,e);
printf("%c",e);
}
Pop(OPTR,e);//左括號出站
}
else{ //其他情況入棧
Push(OPTR,str[i]);
}
}
// 將剩餘運算元輸出
while (!StackEmpty(OPTR)) {
Pop(OPTR,e);
printf("%c",e);
}
}
//中綴表示式求值
char OP[]={'+','-','*','/','(',')','#'};
char Prior[100][100]={">><<<>>",
">><<<>>",
">>>><>>",
">>>><>>",
"<<<<<= ",
">>>>> >>",
"<<<<<< ="};
int Locate(char OP[],char c)
{
int i;
for(i=1;i<=7;i++)
{
if(OP[i]==c)
return i;
}
}
char Compare(char theta1,char theta2)
{
//獲取兩個運算子優先關係
int i,j;
i=Locate(OP,theta1);
j=Locate(OP,theta2);
return Prior[i][j];
}
int Operate(int a,char theta,int b)
{
switch(theta){
case'+':
return a+b;
case'-':
return a-b;
case'*':
return a*b;
case'/':
return a/b;
}
}
int EvaluateExpression(char str[])
{
char *p=str;
int num;
char a,b,ch,theta;
StackPtr OPTR,OPND;
InitStack(OPTR);
Push(OPTR,*p);
p++;
InitStack(OPND);
while(*p!='#'||GetTop(OPTR)!='#'){
if(*p>='0'&&*p<='9'){
num=0;
while(*p!='#'&&*p>='0'&&*p<='9'){
num=num*10+*p-'0';
p++;
}
Push(OPND,num);
}
else
switch(Compare(GetTop(OPTR),*p)){
case'<':Push(OPTR,*p);p++;break;
case'=':Pop(OPTR,ch);p++;break;
case'>':Pop(OPND,b);Pop(OPND,a);
Pop(OPTR,theta);
Push(OPND,Operate(a,theta,b));
break;
}
}
return GetTop(OPND);
int main() {
char str[100];
// 輸入中綴表示式
printf("請輸入中綴表示式:\n>>> ");
scanf("%s", str);
printf("[中綴表示式] %s",str);
//中綴表示式求值
int b=EvaluateExpression(str);
printf("\n中綴求值=%d\n",b);
// 字首表示式
infix_to_prefix(str);
// 字尾表示式
infix_to_suffix(str);
printf("\n");
return 0;
}
測試結構:
…