中缀表达式c++.docx
《中缀表达式c++.docx》由会员分享,可在线阅读,更多相关《中缀表达式c++.docx(13页珍藏版)》请在冰豆网上搜索。
中缀表达式c++
/*模拟小学生在线算术考试系统(C++实现)
*实现的要求:
*1.操作数个数随机指定
*2.操作数随机生成
*3.操作符随机选择
*4.利用中缀表达式堆栈求值法求出正确答案
*5.判断用户输入答案并计算分值
*--------------------------------------
*程序是帮别人写的课程设计时间比较紧迫就没有用链表实现堆栈
*也没有将中缀表达式转换为后缀表达式后再求值
*------------------------------------------
*程序逻辑还算清楚,有详细的注释。
*在vs2010,vs2008下可以正常运行(vc6.0就不用试了不能运行的,不是程序有错误,而是
*vc6.0对局部变量的要求不一样,所以不能运行)
*-------------------------------------------------------------
*2013-1-9By:
LiWei
*/
#include
#include
#include
#include
usingnamespacestd;
#defineMax_Size50//定义最多保存的题目数量
template
classOp_Stack
{
public:
Op_Stack();
voidPush(Ta);//进栈操作
TPOP();//出栈操作
boolisNull();
TTop();
private:
inttop;
TData[19];
};
template
Op_Stack:
:
Op_Stack()
{
top=-1;
}
template
voidOp_Stack:
:
Push(Ta)
{
top++;
Data[top]=a;
}
template
TOp_Stack:
:
POP()
{
Ttemp;
temp=Data[top];
top--;
returntemp;
}
template
boolOp_Stack:
:
isNull()
{
if(-1==top)
{
returnfalse;
}
}
template
TOp_Stack:
:
Top()
{
if(-1==top)
{
return-1;
}
else
{
returnData[top];
}
}
classOP_Questions
{
public:
OP_Questions();
int*Produce_Rand(intbegin,intend,intcount);//产生指定范围内的随机数,返回指向数组的指针
voidProduce_Questions();//生成题目
voidprint();//打印题目
intscore();//计算题目
voidshow_score();//输出用户成绩
voidmenu();//
private:
intquestions[30],num;//保存生成的题目,操作数的个数
Op_Stacknumber;//保存操作数,用于中缀表达式求值
Op_Stackop;//保存操作符,用于中缀表达式求值
intfinalscore;//总成绩
};
OP_Questions:
:
OP_Questions()//构造函数
{
num=0;
finalscore=0;//初始化分数和操作数个数
}
int*OP_Questions:
:
Produce_Rand(intbegin,intend,intcount)//生成所需的随机数
{
int*p=newint[10];
srand((unsigned)time(0));
for(inti=0;i<=count-1;i++)
{
p[i]=rand()%(end-begin+1)+begin;//取得begin到end范围内的随机数
}
returnp;//返回数组首地址
}
voidOP_Questions:
:
Produce_Questions()
{
/*生成随机题目思路:
*1,操作数个数随机生成
*2,操作符随机选择
*3,操作数随机生成
*/
int*p,index;
index=0;
p=Produce_Rand(2,5,1);//随机确定需要的操作数的个数
num=p[0];//记录需要几个操作数
p=Produce_Rand(1,10,num);//取得操作数,为方便计算操作数范围在1—10之间
for(inti=1;i<=2*num-1;i+=2)//将操作数保存在数组中(中缀表达式),奇数位置放操作数
{
questions[i]=*(p+index);
index++;//记录位置
}
p=Produce_Rand(1,4,num-1);/*取得操作符*/
index=0;/*返回的数字表示操作符代号*/
for(inti=2;i<=2*num-1;i+=2)/*1001,1002表示+-,1011,1012表示*/,*/
{/*方便在中缀表达式求值时判断运算符优先级*/
switch(*(p+index))
{
case1:
{
questions[i]=1001;//表示+
}break;
case2:
{
questions[i]=1002;//表示-
}break;
case3:
{
questions[i]=1011;//表示*
}break;
case4:
{
questions[i]=1012;//表示/
}break;
}
index++;
}
deletep;//释放内存
}
voidOP_Questions:
:
print()//显示题目
{
intch;
for(inti=1;i<=2*num-1;i++)//循环2*num-1次依次显示取得的数字打印
{
ch=questions[i];
if(ch<=100)
{
cout<}
else
{
switch(ch)
{
case1001:
{
cout<<"+";
}break;
case1002:
{
cout<<"-";
}break;
case1011:
{
cout<<"*";
}break;
case1012:
{
cout<<"/";
}break;
}
}
}
cout<<"="<}
intOP_Questions:
:
score()//中缀表达式求值
{
intch=0;//记录从questions数组中取得的数字
inttemp=0;//临时变量用于取得操作符栈顶元素和当前ch变量比较运算符优先级
intLeft=0;//表示退栈时的左操作数
intRight=0;//表示退栈时的右操作数
intOP=0;//表示操作符
inti=1;
while(i<=2*num-1)//逐一扫描questions数组
{
ch=questions[i];
if(ch<=100)//是操作数直接进栈
{
number.Push(ch);
i++;
}
else//是操作符
{
if(false==op.isNull())//操作符栈为空直接进栈(只有一个操作符时不用比较优先级)
{
op.Push(ch);
i++;
}
else//不是为空则判断优先级
{
temp=op.Top();//临时取出操作符栈顶元素
if(ch-1>temp)//优先级高进栈
{
op.Push(ch);
i++;
}
else//优先级相同或低于
{
Right=number.POP();//从操作数栈退出两个操作数
Left=number.POP();
OP=op.POP();//并取出一个运算符
switch(OP)
{
case1001:
//然后计算这三个数字表示的数学含义,再将结果放入操作数栈
{
number.Push(Left+Right);
}break;
case1002:
{
number.Push(Left-Right);
}break;
case1011:
{
number.Push(Left*Right);
}break;
case1012:
{
number.Push(Left/Right);
}break;
}
}
}
}
}
/*执行完上面的while循环后
*操作数和操作符栈里边还是有数字并没有得到最终结果
*但是此时再求结果已经不用考虑运算符的优先级了
*所以利用下面的while循环每次从操作数栈取出两个数,从操作符栈取出一个操作符
*计算取得的数学表达式并将结果再次放回操作数栈
*直至操作符栈为空,此时操作数栈还剩下一个数字
*即所求结果
*/
while(false!
=op.isNull())
{
Right=number.POP();
Left=number.POP();
OP=op.POP();
switch(OP)
{
case1001:
{
number.Push(Left+Right);
}break;
case1002:
{
number.Push(Left-Right);
}break;
case1011:
{
number.Push(Left*Right);
}break;
case1012:
{
number.Push(Left/Right);
}break;
}
}
returnnumber.POP();
}
voidOP_Questions:
:
menu()
{
intcount=0;//题目数量
intuser_answer;//用户答案
intsystem_answer;//系统答案
cout<<"请输入题目数量:
";
cin>>count;
for(inti=0;i{
Produce_Questions();
print();
system_answer=score();//取得系统的正确答案
cout<<"输入答案:
";
cin>>user_answer;
if(system_answer==user_answer)
{
finalscore+=5;//每答对一题5分
}
}
}
voidOP_Questions:
:
show_score()
{
cout<<"****************************************"<cout<<"**"<cout<<"**"<cout<<"**"<cout<<"*"<cout<<"**"<cout<<"**"<cout<<"****************************************"<}
intmain()
{
OP_Questionsque;
intselect;
for(;;)
{
cout<<"\t\t********************************************"<cout<<"\t\t**"<cout<<"\t\t**"<cout<<"\t\t\t"<<"随机题目生成"<cout<<"\t\t**"<cout<<"\t\t**"<cout<<"\t\t********************************************"<cout<<"1.开始做题:
"<cout<<"2.显示分数:
"<cout<<"3.退出系统:
"<cout<<"请选择功能:
";
cin>>select;
switch(select)
{
case1:
{
system("cls");
cout<除法【整除取整】"<que.menu();
system("pause");
system("cls");
}break;
case2:
{
system("cls");
que.show_score();
system("pause");
system("cls");
}break;
case3:
{
return0;
}break;
}
}
}