实验课:表达式终于写完喽,为了保健壮性,写完后又加了加了一些条件来判断非法数据;
主程序:
#include<cstdio>
#include<cstring>
#include<conio.h>
#include<Windows.h>
#include "Stack.h"
using namespace std;
#define Error -8
bool Isdig(char ch) {
return (ch>='0'&&ch<='9')?true:false;
}
bool IsOper(char ch)
{
bool a=ch=='+'||ch=='-'||ch=='*'||ch=='/';
bool b=ch=='('||ch==')'||ch=='#';
return a||b;
}
int Precede(char a,char b)
{
int flag=0;
if((a=='('&&b=='#')||(a==')'&&b=='(')||(a=='#'&&b==')')) return Error;
if(!IsOper(a)||!IsOper(b)) return Error;
if(a=='('||a=='#') {
if((a=='('&&b==')')||(a=='#'&&b=='#')) flag=0;
else flag=-1;
}
else if(a=='+'||a=='-') {
if(b=='*'||b=='/'||b=='(') flag=-1;
else flag=1;
}
else if(a=='*'||a=='/') {
if(b=='(') flag=-1;
else flag=1;
}
else {
flag=1;
}
return flag;
}
int Operator(int a,char ch,int b)
{
int c=0;
switch(ch)
{
case '+': c=a+b; break;
case '-': c=a-b; break;
case '*': c=a*b; break;
case '/': c=a/b; break;
}
return c;
}
void EvalateExpression(char str[])
{
Stack<char> optr; Stack<int> opnd;
optr.push('#');
int len=strlen(str); str[len]='#'; str[++len]='\0';
int i=0;
while(!(str[i]=='#'&&optr.top()=='#'))
{
if(Isdig(str[i]))
{
int num=0;
while(Isdig(str[i])) {
num=num*10+str[i]-'0';
++i;
}
opnd.push(num);
}
else {
switch(Precede(optr.top(),str[i]))
{
case -1: optr.push(str[i]); ++i; break;
case 0: ++i; optr.pop(); break;
case 1: {
int top1=opnd.top(); opnd.pop();
int top2=opnd.top(); opnd.pop();
opnd.push(Operator(top2,optr.top(),top1));
optr.pop();
break;
}
default: {
printf("\n\n输入错误,请检查后重试!!!");
return ;
}
}
}
}
printf("计算结果为: %d\n",opnd.top());
// getch();
// opnd.pop();
// optr.clear();
}
int main()
{
system("color 4E");
char str[100];
printf("======================注意: 本系统所有输入均采用英文输入法=======================");
while(1){
// system("CLS");
printf("\n\n请输入您需要计算的算术表达式: ");
scanf("%s",str);
EvalateExpression(str);
}
return 0;
}
头文件Stack.h:
#ifndef Stack_lt2016
#define Stack_lt2016 1
template <typename T>
struct Node{
T date;
struct Node *next;
};
template <class T>
class Stack{
Node<T>* S;
public:
Stack()
{
S=NULL;
}
void push(T a)
{
Node<T>* p=new Node<T>;
p->date=a; p->next=S;
S=p;
return ;
}
void pop()
{
if(S) {
Node<T>* p=S;
S=S->next;
delete p;
}
}
T top()
{
if(S) return S->date;
}
int size()
{
Node<T>* p=S; int i=0;
while(p) ++i, p=p->next;
return i;
}
void clear()
{
while(S) pop();
}
bool empty()
{
return S?true:false;
}
};
#endif