📄 logiccal.h
字号:
//逻辑表达式求值 支持'&' '|' '!' '(' ')'
//变量标识符'd' 例如d1 - 1, d0 - 0 d22 - 22 数据为不大于10位的整数
//源程序清单
//#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define ERROR -1
#define BLANK 0
#define DATA 1
#define KUOHAO1 5
#define KUOHAO2 2
#define ADD_OR_SUB 3
#define MUT_OR_DIV 4
#define PREDATA 6
#define DATA_MAXSIZE 10
//char Exp[EXPMAXSIZE] = "d1|(d0&d3)|d0|(!d22);";
template <class Elem>class Stack;
template <class Elem>
class StackNode //堆栈的结点类
{
friend class Stack<Elem>;
Elem elem;
StackNode<Elem> *link;
StackNode (Elem e=0, StackNode<Elem> *l=NULL):elem(e),link(l)
{
//cout<<"elem is : "<<e<<endl;
}
};
template <class Elem>
class Stack
{
int number;
StackNode<Elem> *head;
public:
Stack():number(0),head(NULL){}
~Stack()
{
StackNode<Elem> *tmp=head;
while(head!=NULL)
{
head=head->link;
delete tmp;
tmp=head;
}
}
void Push(const Elem &e)
{
number++;
head=new StackNode<Elem>(e, head);
}
void MakeEmpty()
{
StackNode<Elem> *tmp=head;
while(head!=NULL)
{
head=head->link;
delete tmp;
tmp=head;
}
number=0;
}
void Pop()
{
assert(number!=0);
number--;
StackNode<Elem> *tmp=head;
head=head->link;
delete tmp;
}
Elem GetHead()
{
return head->elem;
}
int GetNumber() const { return number; }//返回堆栈中元素的数目
};
//计算类
class Caculator
{
private:
Stack<double> data;//数据栈
Stack<char> sign;//运算符栈
int flag; //标志位表示前一个输入的是数还是一个运算符
char *pExpress;
public:
Caculator()
{
flag=BLANK;
pExpress = NULL;
}
Caculator(char *pbuf)
{
flag = BLANK;
pExpress = pbuf;
}
~Caculator(){}
int Prior(char ch) const// 返回运算符的优先级
{
switch(ch)
{
case ')': return 1;
/* case '+':
case '-': return 2;*/
case '!':
case '|':
case '&': return 2;
case '*':
case '/': return 3;
case '(': return 5;
default: return -1;
}
}
void clearstream()// 清空输入流
{
// char ch;
// while(cin>>ch, ch!=';') ;
}
void done(char ch)//做一次二元运算
{
double a, b;
a=data.GetHead(); data.Pop();
b=data.GetHead(); data.Pop();
switch(ch)
{
/* case '+': b+=a;break;
case '-': b-=a;break;
case '*': b*=a;break;
case '/': b/=a;break;*/
case '!': b = !a; break;
case '|': b =(b||a);break;
case '&': b =(b&&a);break;
default : break;
}
data.Push(b);
}
char* Caculate()//计算主体
{
char ch;
double d;
char cha[DATA_MAXSIZE];
int k=0;
bool bfind1=0;
/* for(int j=0;j<EXPMAXSIZE;j++)
{
if(Exp[j]==';')
{
bfind1 =1;
break;
}
}*/
int i=0;
while(pExpress[i]!='\0')
{
if(pExpress[i]==';')
{
bfind1 = 1;
break;
}
i++;
}
if(bfind1==0)
{
// cout<<"Error input! 表达式缺少结束符';'"<<endl;
flag=ERROR;
clearstream();
return "表达式缺少结束符!";
}
while(ch = pExpress[k],k++,ch!=';')
//while(cin>>ch, ch!=';')
{
// if(ch>='0' && ch<='9' || ch=='.')//如果是一个0-9的数, 则输入一个实数
if(ch== 'd')
{
if(flag==DATA)
{
// cout<<"Error input! 数字连写了"<<endl;
flag=ERROR;
clearstream();
return "数字连写了!";
}
// cin.putback(ch);
// cin>>d;
// d = atof(&ch);
bool bFind = 0;
for(int i=0;i<DATA_MAXSIZE;i++)
{
if( pExpress[k+i]>='0' && pExpress[k+i]<='9')
{
cha[i] = pExpress[k+i];
bFind = 1;
}
else
break;
}
if(bFind)
{
k = k+i;
d = atof(cha);
data.Push(d);
flag=DATA;
}
else
{
// cout<<"Error input! 标识符后少了数据"<<endl;
flag = ERROR;
clearstream();
return "标识符后少了数据!";
}
}
else if(ch>='0' && ch<='9')//如果是一个0-9的数, 则输入一个实数
{
// cout<<"Error input! 数据前少了标识符"<<endl;
flag = ERROR;
clearstream();
return "数据前少了标识符!";
}
else//如果输入的是字符, 则作出判断
{
int prio=Prior(ch);
char tempch, chprior;
switch( prio )
{
case -1:
// cout<<"Error input! 不允许的字符"<<endl;//非法字符
flag=ERROR;
clearstream();
return "不允许的字符!";
case 1: // 如果是一个后括号,
if(flag==ADD_OR_SUB || flag==MUT_OR_DIV)//如果运此括号前是一个运算符,则提示出错
{
flag=ERROR;
clearstream();
// cout<<"Error input! 运算符后少了数据"<<endl;
return "运算符后少了数据!";
}
//如果它前面的是前括号,则表明括号中间没在数据,提示出错
if( flag==KUOHAO1 )
{
// cout<<"ERROR! 括号中间没在数据"<<endl;
flag=ERROR;
clearstream();
return "括号中间没在数据!";
}
tempch=sign.GetHead(); //是合法的运算, 取一个运算符
flag=KUOHAO2;
while(tempch!='(') //做完这一重括号内的所有运算
{
sign.Pop();
done(tempch);
if(sign.GetNumber()!=0)
{
tempch=sign.GetHead();
}
else //如果当前的后括号没有找到与其配对的前括号, 则提示出错
{
// cout<<"Error input! 括号不配对"<<endl;
flag=ERROR;
clearstream();
return "括号不配对!";
}
}
sign.Pop();
break;
case 2: //如果读入的是一个 + 或者 - 号,
//它前面的是一个 + 或者 - 号, 由提示出错
if(flag==ADD_OR_SUB || flag==MUT_OR_DIV )
{
cout<<"Error input! 运算符连用"<<endl;
flag=ERROR;
clearstream();
return "运算符连用!";
}
//如果+前面没有数据,或者+是被写在括号里的,则向它的前面压入一个0到data
if( flag==BLANK || data.GetNumber() == 0 || flag == KUOHAO1 )
{
// data.Push(0);//push 0 to stack
if(ch=='|') data.Push(0);
else if(ch=='&') data.Push(1);
else if(ch=='!') data.Push(0);
}
//如果它前面是一个后括号,因后括号里的内容已经做过运算,故只当一个一般的来做
if( flag== KUOHAO2 || flag == DATA )
{
while( sign.GetNumber() && sign.GetHead()!='(' && Prior( sign.GetHead() ) >= Prior(ch) )
{
done( sign.GetHead() );
sign.Pop();
}
}
flag = ADD_OR_SUB;
sign.Push( ch );
break;
case 3: // 如果当前输入是一个 * 或者 / 号
//如果前一个输入是一个 * 或者 / 号
if(flag==MUT_OR_DIV || flag==ADD_OR_SUB )
{
cout<<"Error input! 运算符连用"<<endl;
flag=ERROR;
clearstream();
return "运算符连用!";
}
//如果前面是一个前括号
if( flag==KUOHAO1 )
{
cout<<"ERROR! * / 不能直接接在( 后"<<endl;
flag=ERROR;
clearstream();
return "* / 不能直接接在( 后!";
}
//如果它放在了表达式的开头
if(data.GetNumber()==0)
{
cout<<"Error input! * 或 / 不能放在表达式的开头"<<endl;
flag=ERROR;
clearstream();
return "* 或 / 不能放在表达式的开头!";
}
//如果它前面不只一个数字, 则做它前面的运算
if(data.GetNumber()!=1)
{
chprior=Prior(sign.GetHead());
if(chprior>=Prior(ch) && sign.GetHead()!='(')
{
chprior=sign.GetHead();
sign.Pop();
done(chprior);
}
}
sign.Push(ch);
flag=MUT_OR_DIV;
break;
case 5://如果当前的是一个前括号
// 如果它前面输入的是一个数据,则提示出错
if(flag==DATA)
{
// cout<<"Error input! 数据后不能直接跟括号"<<endl;
flag=ERROR;
clearstream();
return "数据后不能直接跟括号!";
}
sign.Push(ch);
flag=KUOHAO1;
break;
default :
// cout<<"Error input! 非法字符: "<<ch<<endl;
flag=ERROR;
clearstream();
return "非法字符!";
break;
}
}
}
if( sign.GetNumber() && sign.GetHead() == '(' )
{
// cout<<"ERROR! 括号不配对!"<<endl;//前括号没有找到后括号
flag=ERROR;
return "括号不配对!";
}
if( flag==MUT_OR_DIV || flag == ADD_OR_SUB)
{
// cout<<"ERROR!表达式没有写完"<< endl;
flag=ERROR;
return "表达式没有写完!";
}
while(sign.GetNumber())
{
if( sign.GetHead() == '(' )
{
// cout<<"ERROR! 括号不配对!"<< endl;
flag = ERROR;
return "括号不配对!!";
}
done(sign.GetHead());
sign.Pop();
}
return "表达式正确!";
}
int OutPut()
{
int ans=0;
if(flag==ERROR)
{
// cout<<"输入错误<! NO ANSWER !>"<<endl;
ans = -1;
}
else if(data.GetNumber()==0)
{
// cout<<"空表达式:无结果!"<<endl;
ans = -2;
}
else
{
// cout<<" 答 案 = "<<data.GetHead()<<endl;
ans = (int)data.GetHead();
data.Pop();
}
return ans;
}
void EnEmpty()
{
data.MakeEmpty();
sign.MakeEmpty();
flag=BLANK;
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -