6263:布尔表达式:输入一个布尔表达式,请你输出它的真假值
样例输入:
( V | V ) & F & ( F| V)
!V | V & V & !F & (F | V ) & (!F | F | !V & V)
(F&F|V|!V&!F&!(F|F&V))
思路:本题的关键就是定义优先级,表中含义是后来的符号是小于、等于、或者大于先前的符号。其中若符号相同先入的普遍大于后入的。对于“(”和“)”必须仔细考虑。如栈有"("则之后的符号都大,必须压入栈。目前读到“(”则此时它比任何符号都要小,直接入栈。目前读到“)”它优先级最大,必须把能计算的计算完,直到遇到“=”。可以这么考虑:即目前读入的需要压入栈的则优先级小。在栈中要一直保持优先级高的在上面。其中“0”代表非法的比较,或者说表达式中不存在这种情况。
先\后 | & ! ( ) #
| > < < < > >
& > > < < > >
! > > = < > >
( < < < < = 0
) > > > 0 > >
# < < < < 0 =
注意:
1、此题的两个“!”之间是=的优先级,即相互抵消
2、注意若出现>则需要循环计算到!=>为止
3、bool型不能用~取反,只能用1-n[ntop-1]
#include<cstdio>
#include<iostream>
#include<string>
#include<map>
using namespace std;
map<char,int>index;//| & ! ( ) #
char pri[7][7]={ {'>','<','<','<','>','>'},//|
{'>','>','<','<','>','>'},//&
{'>','>','=','<','>','>'},//!
{'<','<','<','<','=','0'},//(
{'>','>','>','0','>','>'},//)
{'<','<','<','<','0','='}};//#
char get(char a,char b)
{
int ida=index[a],idb=index[b];
return pri[ida][idb];
}
void solve(string s)
{
bool n[100];
char o[100],x,op;
int ntop=0,otop=0;
int i=0;
o[otop++]='#';//添加#
for (i=0;i<s.length();i++)
{
if (s[i]=='V') n[ntop++]=1;
else if (s[i]=='F') n[ntop++]=0;
else //op
{
x=get(o[otop-1],s[i]);
while(x=='>')
{
op=o[otop-1];otop--;
switch (op)
{
case '|': n[ntop-2]=n[ntop-2]|n[ntop-1];ntop--;break;
case '&': n[ntop-2]=n[ntop-2]&n[ntop-1];ntop--;break;
case '!': n[ntop-1]=1-n[ntop-1];break;
}
x=get(o[otop-1],s[i]);
}
if (x=='=')
otop--;
else if (x=='<')
o[otop++]=s[i];
}
}
if (n[0]==1)cout<<"V"<<endl;
else cout<<"F"<<endl;
}
int main()
{
index['|']=0;index['&']=1;index['!']=2;index['(']=3;index[')']=4;index['#']=5;//初始化索引
int i;
string s,temp;
while(getline(cin,s))
{
i=0;temp="";//注意temp清空
while(i<s.length())//除空格
{
while(s[i]==' ')i++;
temp+=s[i]; i++;
}
temp+="#";//表达式结束
solve(temp);
}
return 0;
}
01:简单算术表达式求值——计算变为数字
#include<iostream>
#include<map>
#include<string>
using namespace std; //+ - * / % #
char pri[6][6]={/*+*/{'>','>','<','<','<','>'},
/*-*/{'>','>','<','<','<','>'},
/***/{'>','>','>','>','>','>'},
/*/*/{'>','>','>','>','>','>'},
/*%*/{'>','>','>','>','>','>'},
/*#*/{'<','<','<','<','<','='}};
map<char,int>index;
char getpri(char a,char b)
{
int ida=index[a],idb=index[b];
return pri[ida][idb];
}
int main()
{
int i;
string s,temp="";
char o[100],x,op;
int n[100],ntop=0,otop=0,t;
index['+']=0;index['-']=1;index['*']=2;index['/']=3;index['%']=4;index['#']=5;
getline(cin,s);
i=0;
while(i<s.length())
{
while(s[i]==' ')i++;
temp+=s[i];i++;
}
s=temp+"#";t=0;
o[otop++]='#';
for (i=0;i<s.length();i++)
{
if (isdigit(s[i]))
t=t*10+s[i]-'0';
else
{
n[ntop++]=t;t=0;
x=getpri(o[otop-1],s[i]);
while(x=='>')
{
op=o[otop-1];otop--;
switch (op)
{
case'+':n[ntop-2]=n[ntop-2]+n[ntop-1];ntop--;break;
case'-':n[ntop-2]=n[ntop-2]-n[ntop-1];ntop--;break;
case'*':n[ntop-2]=n[ntop-2]*n[ntop-1];ntop--;break;
case'/':n[ntop-2]=n[ntop-2]/n[ntop-1];ntop--;break;
case'%':n[ntop-2]=n[ntop-2]%n[ntop-1];ntop--;break;
}
x=getpri(o[otop-1],s[i]);
}
if (x=='=') otop--;
else if (x=='<') o[otop++]=s[i];
}
}
cout<<n[0]<<endl;
return 0;
}
【终极综合运用】:4132:四则运算表达式求值:包含括号、数字、小数点
注意很多函数要包含头文件
<iomanip> setiosflags(ios::fixed)<<setprecision(2)
<ctype.h> isdight()
<cmath> pow()
#include<iostream>
#include<map>
#include<string>
#include<ctype.h>
#include<cmath>
#include<iomanip>
using namespace std;// + - * / ( ) #
char pri[7][7]={/* + */ {'>','>','<','<','<','>','>'},
/* - */ {'>','>','<','<','<','>','>'},
/* * */ {'>','>','>','>','<','>','>'},
/* / */ {'>','>','>','>','<','>','>'},
/* ( */ {'<','<','<','<','<','=','0'},
/* ) */ {'>','>','>','>','0','>','>'},
/* # */ {'<','<','<','<','<','0','='}};
map<char,int>index;
double n[100];
char getpri(char a,char b)
{
int x=index[a],y=index[b];
return pri[x][y];
}
int main()
{
index['+']=0;index['-']=1;index['*']=2;index['/']=3;index['(']=4;index[')']=5;index['#']=6;
char o[100],x,op;
int ntop=0,otop=0,i,len=0;
double n1=0,n2=0;
bool xiaoshu=false,isnumber=false;
string s;
getline(cin,s);
s=s+"#";
o[otop++]='#';
for (i=0;i<s.length();i++)
{
if (isdigit(s[i]))
{
isnumber=true;
if (xiaoshu)
{
n2=n2*10+s[i]-'0';
len++;
}
else n1=n1*10+s[i]-'0';
}
else if (s[i]=='.') xiaoshu=true;
else//op
{
if (isnumber)//防止出现两个符号连续的情况
n[ntop++]=n1+(float)pow(10,0-len)*n2;//数字入栈
xiaoshu=false;isnumber=false;len=0;n1=0;n2=0;//初始化
x=getpri(o[otop-1],s[i]);//获取优先级
while(x=='>')
{
op=o[otop-1];otop--;
switch (op)
{
case '+':n[ntop-2]=n[ntop-2]+n[ntop-1];ntop--;break;
case '-':n[ntop-2]=n[ntop-2]-n[ntop-1];ntop--;break;
case '*':n[ntop-2]=n[ntop-2]*n[ntop-1];ntop--;break;
case '/':n[ntop-2]=n[ntop-2]/n[ntop-1];ntop--;break;
}
x=getpri(o[otop-1],s[i]);
}
if (x=='=') otop--;
else if (x=='<') o[otop++]=s[i];
}
}
cout<<setiosflags(ios::fixed)<<setprecision(2)<<n[0]<<endl;
return 0;
}
心得:表达式求值真的是掌握方法就很简单,第一道题花了很久,主要是有关算法都不记得了,重新温故,才慢慢理清思路。最重要的就是找好优先级。其他的都很简单,注意细节就好。