算法:
1.先利用ARR[]存储所需要计算的表达式字符串;
opnd存储操作数的栈,optr存储运算符的栈;
arr[]存储连续的数字字符,然后转化的整型数;
2.依次读入ARR[]的每个字符(flag为标记),如果是数字字符转化后入opnd栈;
3.如果是运算符,则比较读入的字符与optr栈顶的运算符,根据事先确定的顺序决定是继续读入,是提取opnd的两个操作数计算,还是消除括号;
4.当读入’=’时,运算结束,输出opnd栈顶元素即为运算结果;
总结:对栈有进一步的理解,对结构的控制进一步掌握
漏洞:
1.由于创建optr时,事先存入了’=’所以,如果负数放在第一位则计算不对,其他漏洞没有发现
2.对析构函数的使用不对,加上析构函数会出现问题,需要进一步学习析构函数的使用
#include<iostream>
#include<stdlib.h>//包含atoi()和itoa()函数
using namespace std;
#define MAX 50
#define NULL 0
typedef struct //运算符栈
{
char arr[MAX];
int top;
}OPTR;
typedef struct //操作数栈
{
int arr[MAX];
int top;
}OPND;
class A
{
public:
A();//构造函数
void load();//依次读入每个字符
void Create();
int Empty(OPTR *optr);//判空
int Empty(OPND *opnd);//判空
void Push(char ch);//运算符入栈
void Push(int num);//操作数入栈
int Pop(char *ch);//运算符出栈
int Pop(int *num);//操作数出栈
int bijiao(char ch);//比较算符优先级,确定是否计算
int jisuan(int a , int b , char ch);//计算
int get_opnd_top();//返回运算符的栈顶元素(结果数值)
int pankong();//判断运算符是否结束
private:
char ARR[100] ;
OPTR *optr;
OPND *opnd;
int flag;
};
///////////////////////////构造函数/////////////////////////
A::A()
{
flag = 0;
optr = NULL;
opnd = NULL;
cout<<"输入计算的表达式:";
cin>>ARR;
}
///////////////////////////析构函数///////////////////////
//A::~A()
//{
// delete []ARR ;
// delete optr ;
// delete opnd;
//}
///////////////////////////依次读入每个字符////////////////
void A::load()
{
int a = 0 , b = 0 ,length = strlen(ARR) ;
char arr[10] = {0} , ch ;
for (int i = 0 ; i < length; )
{
i = flag;
if (pankong()){ break;}
if (ARR[i] =='+'||ARR[i] =='-'||ARR[i] =='*'||ARR[i] =='/'||ARR[i] =='('||ARR[i] ==')'||ARR[i] =='=')//是运算符;
{
int n = bijiao(ARR[i]);//取得比较返回值
switch (n)
{
case 1:{ Push(ARR[i]);flag++;}break;//继续入栈,flag++读取下一个位置
case 0:{ Pop(&ch); ch = 0 ; flag++;}break;//')'遇到'(',把'('出栈,flag++读取下一个位置
case -1:{ //进行计算
a = Pop(&a);
b = Pop(&b);
ch = Pop(&ch);
Push(jisuan(b , a , ch));//计算结果入栈
}break;
}
}
else //是字符数
{
for (int j = 0 ; i < strlen(ARR) - 1;)
{
if (ARR[i] !='+'&&ARR[i] !='-'&&ARR[i] !='*'&&ARR[i] !='/'&&ARR[i] !='('&&ARR[i] !=')')//把字符保存在arr[]中
{
arr[j] = ARR[i] ;
j++;
}
else
break;
i++;
}
flag = i ; //标记读入位置
Push( atoi(arr) );//把arr[]字符数组,转化成int型数,入操作数栈
for (int i = 0 ;i < 10 ;i++)
{
arr[i] = 0;
}
}
}
}
///////////////////////////创建/////////////////////////
void A::Create()//初始化运算符栈,并将'='输入进去!
{
optr = new OPTR;
optr->top = 0;
optr->arr[optr->top] = '=' ;
opnd = new OPND;//初始化操作数栈!
opnd->arr[100] = 0 ;
opnd->top = -1;
}
///////////////////////////判断栈空/////////////////////////
int A:: Empty(OPTR *optr)//判断操作数是否栈空
{
if (optr->top == -1)
return 1;
else
return 0;
}
int A::Empty(OPND *opnd)//判断运算符是否栈空
{
if (opnd->top == -1)
return 1;
else
return 0;
}
///////////////////////////入栈/////////////////////////
void A::Push(char ch)//运算符入栈
{
optr->top++;
optr->arr[optr->top] = ch;
}
void A::Push(int num)//操作数入栈
{
opnd->top++;
opnd->arr[opnd->top] = num;
}
///////////////////////////出栈/////////////////////////
int A::Pop(char *ch)//运算符出栈
{
*ch = optr->arr[optr->top];
optr->top--;
return *ch;
}
int A::Pop(int *num)//操作数出栈
{
*num = opnd->arr[opnd->top];
opnd->top--;
return *num;
}
///////////////////////////判断优先级/////////////////////////
int A::bijiao(char ch)
{
int in_temp = 0 , out_temp = 0;
switch (ch)//栈外运算符
{
case '(':out_temp = 6;break;
case '+':
case '-':out_temp = 1;break;
case '*':
case '/':out_temp = 3;break;
case ')':out_temp = 0;break;
case '=':out_temp = -1;break;
}
switch (optr->arr[optr->top])//OPTR栈顶的运算符
{
case '(':in_temp = 0;break;
case '+':
case '-':in_temp = 2;break;
case '*':
case '/':in_temp = 4;break;
case ')':in_temp = 6;break;
case '=':in_temp = -2;break;
}
if (out_temp > in_temp){return 1;}//栈外运算符高返回1,继续入栈;
if (out_temp == in_temp){return 0;}//栈外运算符低返回0,进行消括号;
if (out_temp < in_temp){return -1;}//栈外运算符低返回-1,进行计算;
}
///////////////////////////计算/////////////////////////
int A::jisuan(int a , int b , char ch)
{
switch (ch)
{
case '+':return (a + b);
case '-':return (a - b);
case '*':return (a * b);
case '/':return (a / b);
}
}
///////////////////////////判断是否结束('='遇到'=')//////////////////////
int A::pankong()
{
if (optr->arr[1] == '=')
return 1;
else
return 0;
}
///////////////////////////返回Opnd的栈顶元素(结果)////////////////
int A::get_opnd_top()
{
return opnd->arr[opnd->top];
}
///////////////////////////主函数/////////////////////////
int main ()
{
A mess;//构造函数中提示输入ARR;
mess.Create();
mess.load();
cout<<mess.get_opnd_top()<<endl;
system ("pause");
}