1.中綴表達式求值
兩個棧:OPND(double類數),OPTR(操作符)。
需要比較棧裏和棧外ch的操作符優先級。
運用到atof()函數(stdlib.h),將*char 轉換爲 double。
#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdlib.h>
using namespace std;
#define MAXSIZE 1000
typedef struct
{
double *base;
double *top;
int stacksize;
}SqStack_d;
void Init(SqStack_d &S)
{
S.base = new double[MAXSIZE];
S.top = S.base;
S.stacksize = MAXSIZE;
}
void Push(SqStack_d &S, double e)
{
if(S.top - S.base != S.stacksize)
{
*S.top = e;
S.top++;
}
}
void Pop(SqStack_d &S, double &e)
{
if(S.top !=S.base)
{
S.top--;
e = *S.top;
}
}
double GetTop(SqStack_d S)
{
if(S.base !=S.top)
{
return *(S.top-1);
}
}
typedef struct
{
char *base;
char *top;
int stacksize;
}SqStack_c;
void Init(SqStack_c &S)
{
S.base = new char[MAXSIZE];
S.top = S.base;
S.stacksize = MAXSIZE;
}
void Push(SqStack_c &S, char e)
{
if(S.top - S.base != S.stacksize)
{
*S.top = e;
S.top++;
}
}
void Pop(SqStack_c &S, char &e)
{
if(S.top !=S.base)
{
S.top--;
e = *S.top;
}
}
char GetTop(SqStack_c S)
{
if(S.base !=S.top)
{
return *(S.top-1);
}
}
bool In( char ch)
{
if(ch>='0'&&ch<='9')
{
return true;
}
else return false;
}
char Com(char c1,char c2) //c1:in c2:out or ch
{
if((c1=='('&&c2==')')||(c1=='='&&c2=='='))
return '=';
else if(((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='='))||((c1=='*'||c1=='/'||c1==')')&&(c2=='+'||c2=='-'||c2=='*'||c2=='/'||c2==')'||c2=='=')))
return '>';
else return '<';
}
double Operate(double a,char x,double b) // ASCALL
{
switch(x)
{
case '+':
return (a+b);
break;
case '-':
return (a-b);
break;
case '*':
return (a*b);
break;
case '/':
return (a/b);
break;
}
}
double Expression(char s[])
{ // 5*(7-3)#
SqStack_d OPND;
SqStack_c OPTR;
Init(OPND);
Init(OPTR);
Push(OPTR,'='); //# 要入棧
char ch;
int k=0;
ch = s[k];
double item;
while(ch != '=' || GetTop(OPTR)!='=') // GetTop(OPTR)!='=' 防止ch== '=',OPTR中還有操作符
{
if(In(ch)) // ch = 4 .5
{
char sd[MAXSIZE];
memset(sd,0,sizeof(sd));
int i=0;
while((ch>='0'&&ch<='9')||(ch=='.'))
{
sd[i] = ch;
k++;
ch = s[k];
i++;
}
item = atof(sd);
Push(OPND,item);
}
else
{
switch(Com(GetTop(OPTR),ch))
{
case '<':
{
Push(OPTR,ch);
k++;
ch = s[k];
break;
}
case '>':
{
double a,b;
char op;
Pop(OPTR,op);
Pop(OPND,a);
Pop(OPND,b);
Push(OPND,Operate(b,op,a));
break; // can't cin>>ch
}
case '=':
{
char x;
Pop(OPTR,x);
k++;
ch = s[k];
break;
}
}
}
}
return GetTop(OPND);
}
int main()
{
char s[MAXSIZE];
while(1)
{
cin>>s;
if(s[0] == '=')
{break;}
cout<<setiosflags(ios::fixed)<<setprecision(2)<<Expression(s)<<endl;
}
return 0;
}
還待優化:兩個棧,如何用一個共享棧,共用體結構;是否可以只用一個char棧
2. 後綴表達式求值
後綴表達式(從左向右掃描),表達式中的操作符已包含優先級,且無括號操作符,無需再比較優先級。
比中綴表達式簡單
一個棧:OPND(double操作數)
#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdlib.h>
using namespace std;
#define MAXSIZE 1000
typedef struct
{
double *base;
double *top;
int stacksize;
}SqStack_d;
void Init(SqStack_d &S)
{
S.base = new double[MAXSIZE];
S.top = S.base;
S.stacksize = MAXSIZE;
}
void Push(SqStack_d &S, double e)
{
if(S.top - S.base != S.stacksize)
{
*S.top = e;
S.top++;
}
}
void Pop(SqStack_d &S, double &e)
{
if(S.top !=S.base)
{
S.top--;
e = *S.top;
}
}
double GetTop(SqStack_d S)
{
if(S.base !=S.top)
{
return *(S.top-1);
}
}
double Operate(double a,char x,double b) // ASCALL
{
switch(x)
{
case '+':
return (a+b);
break;
case '-':
return (a-b);
break;
case '*':
return (a*b);
break;
case '/':
return (a/b);
break;
}
}
double Expression(char s[])
{ // 12+=
SqStack_d OPND;
Init(OPND);
char ch;
int k=0;
ch = s[0];
while(ch != '=') // OPND不足,有剩
{
if(ch>='0'&&ch<='9')
{
int flag =1;
double x;
x = ch-48;
Push(OPND,x);
}
else
{
int flag = 0;
double a,b;
Pop(OPND,a); //2
Pop(OPND,b); //1
Push(OPND,Operate(b,ch,a));
}
k++;
ch = s[k];
}
return GetTop(OPND);
}
int main()
{
char s[MAXSIZE];
while(1)
{
cin>>s;
if(s[0] == '=')
{break;}
cout<<setiosflags(ios::fixed)<<setprecision(2)<<Expression(s)<<endl;
}
return 0;
}
3.中綴轉後綴
一個 棧:OPTR(操作符)
從左向右掃描 中綴表達式 :
遇數,輸出;
遇符:
棧裏<棧外,棧外進棧,輸入下一個字符;
棧裏==棧外,pop,輸入下一個字符;
棧裏>棧外,棧裏pop,並輸出。
#include<iostream>
#include<string>
using namespace std;
#define MAXSIZE 1000
typedef struct
{
char *base;
char *top;
int stacksize;
}SqStack_c;
void Init(SqStack_c &S)
{
S.base = new char[MAXSIZE];
S.top = S.base;
S.stacksize = MAXSIZE;
}
void Push(SqStack_c &S, char e)
{
if(S.top - S.base != S.stacksize)
{
*S.top++ = e;
}
}
void Pop(SqStack_c &S, char &e)
{
if(S.top !=S.base)
{
S.top--;
e = *S.top;
}
}
char GetTop(SqStack_c S)
{
if(S.base !=S.top)
{
return *(S.top-1);
}
}
char Com(char c1,char c2)
{
if(((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='='))||((c1=='*'||c1=='/'||c1==')')&&(c2=='+'||c2=='-'||c2=='*'||c2=='/'||c2==')'||c2=='=')))
{
return '>';
}
else if((c1=='='&&c2=='=')||(c1=='('&&c2==')'))
{
return '=';
}
else
{
return '<';
}
}
void Mid_to_Pos(string s)
{
SqStack_c OPTR;
Init(OPTR);
int k=0;
char ch = s[0];
Push(OPTR,'=');
while(ch!='=' || GetTop(OPTR)!= '=')
{
if(ch>='0'&&ch<='9')
{
cout<<ch;
ch = s[++k];
}
else
{
switch(Com(GetTop(OPTR),ch))
{
case '>':
char e;
Pop(OPTR,e);
cout<<e;
break;
case '<':
Push(OPTR,ch);
ch = s[++k];
break;
case '=':
char x;
Pop(OPTR,x);
ch = s[++k];
break;
}
}
}
cout<<endl;
}
int main()
{
while(1)
{
string s;
cin>>s;
if(s =="=")
{
break;
}
Mid_to_Pos(s);
}
}
4.關於前綴
中綴表達式“1+((2+3)4)-5” 轉前綴:- + 1 + 2 3 4 5
前綴求值,中綴轉前綴: 與後綴表達式不同之處:從右至左掃描,最終逆序輸出(輸出時操作符在前,操作數在後。)。