1.本次作业要求实现核心算法,请将表达式生成的代码及相关的检验、计算表达式结果的代码贴在博客中,并对代码进行必要的解释。
个人能力不足,最终通过搜索找到了栈实现计算器的方法,我看的这一篇图文并茂,挺好理解的:中缀表达式转换成后缀表达式并求值。
各项分部工作基本完成,但是程序还不能运行,在debug。//现在已经可以运行了,错误原因是头文件中函数声明与定义时不符合;还有一个是中缀表达式中多保留了一个等号。
程序不足在于放弃了分数的计算。
利用STL的栈实现后缀表达式的转化
/*
遍历表达式,根据当前字符情况进行不同操作:
1)如果遇到操作数,我们就直接将其输出到后缀表达式中。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出到后缀表达式中直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,
才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。
5)如果我们读到了表达式的末尾,则将栈中所有元素依次弹出至后缀表达式中。
*/
for(i=0;i<len;i++)
{
temp=exp[i];
if(temp=='(') //左括号入栈
st.push(temp);
else if(temp==')') //遇到右括号,直到遇到左括号,其间全部弹出
{
while(st.top()!='(')
{
backexp[j]=st.top();
j++;
st.pop();
}
st.pop();
}
else if(temp>=48&&temp<=57) //操作数入栈
{
st.push(temp);
}
else
{
while(st.empty()==false&&isadvancer(st.top(),temp)==true) //遇到操作符 ,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止
{
backexp[j]=st.top();
j++;
st.pop();
}
st.push(temp); //之后将遇到的操作符压入到栈中
}
}
while (st.empty()==false) //读到了表达式的末尾,则将栈中所有元素依次弹出至后缀表达式中。
{
backexp[j]=st.top();
j++;
st.pop();
}
backexp[j]=0;
实现后缀表达式的求值
/*
得到后缀表达式,遍历,遇到数则入栈,遇到操作符就拿出刚刚进栈的两个数运算,得到的新的数字代替前两个数进栈。最后栈中只剩下一个元素,即算式答案。
因为每次只用到两个操作数,检验非法也变得方便,只要检查除数是不是等于零就可以了。
有两个地方需要注意:
1.数字在栈中的存储方式。数字们在存入栈前先减去‘0’,得到的是一个新的字符,我们进行计算时利用的是它的ascii码值;因而最后栈顶的元素的ascii码值才是我们要的答案,用一个int型变量intans存储它就得到答案。
2.对于除法和减法,要注意运算数的主宾关系。先从栈中得到的那一个数是原先算式中运算符后面的那一个,比如a-b,先从栈中得到的是b,赋值给num1,后得到a,赋值给num2,所以应该用后得到的减去先得到的即num2-num1。为防止出错,四种运算可以统一写成num2操作符(+、-、*、/)num1。
*/
for(int i=0;i<len;i++)
{
temp=backexp[i];
if(temp>=48&&temp<=57) //数字进栈
{
st.push(temp-'0');
}
else //不同操作符进行相应计算,新数字入栈
{
char num1,num2,newnum;
num1=st.top();
st.pop();
num2=st.top();
st.pop();
if(temp=='+')
{
newnum=num1+num2;
st.push(newnum);
}
else if(temp=='-')
{
newnum=num2-num1; //区分减数与被减数
st.push(newnum);
}
else if(temp=='*')
{
newnum=num1*num2;
st.push(newnum);
}
else
{
if(num1==0) //除数为零
{
ans="error";
cout<<ans<<endl;
return 0;
}
newnum=num2/num1; //区分除数与被除数
st.push(newnum);
}
}
}
intans=st.top(); //最后栈顶数字即答案
2.对界面编程的探索
又是一大堆新的东西。
唯一感到亲切的是QT designer(“其设计文件由XML代码构成,是一种标记语言”)。在QT的帮助文档中看到一个恰当的形容--what-you-see-is-what-you-get (WYSIWYG)。
QT designer部件分类与名称找到一篇博文Qt入门学习——常用部件介绍 。
拖出了一个界面
找到了QT入门教程Qt 学习之路 2 ,我觉得很好很全面很细致!
做一些笔记:
1.GUI和API
这两个词的出现频率挺高的。摘自百度百科:图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面;API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
跟着教程写的hello world