关于改良报告与学习总结(Ⅰ)
前言:
在上一篇的博文留言中,我很高兴能够得到大家的帮助与指点,这使得我对于原本存在的问题进行了再一次的回顾与修缮,并且在这过程当中再一次的有所收获,虽然还不能尽善尽美的完成debug任务,虽然整体程序的运行还是存在着问题,但已经就最初的程序进行了改良,在此作出我的改良报告与学习总结。
Part one 问题解决与初尝试构想
关于除连乘问题的解决
就问题存在的特殊性,我们使用if语句来进行了问题的排除。对分子重置的问题也运用k值来进行了避免。(关于规范性上,更正了拼音混杂专有名称的现象)
int numerator=0,denominator=1;
for(j=0;j<3;j++)
{
if(c[0]=='/'&&c[2]=='/'&&c[1]=='+')
{
numerator=d[0]*d[3]+d[2]*d[1];
denominator=d[1]*d[3];
c[1]=0;
break;
}
if(c[j]=='*')
{
d[j+1]*=d[j];
d[j]=0;
c[j]='+';
}
if(c[j]=='/')
{
if(k==0) numerator=d[j];
denominator*=d[j+1];
d[j+1]=d[j];
d[j]=0;
k++;
if(c[j+1]=='*')
{
numerator*=d[j+2];
j++;
if(c[j+1]=='*')
{
numerator*=d[j+2];
j++;
}
}
}
}
关于分母出现负数问题的解决
我们采取的约分运算中,使得分母有些情况会带上符号,这对后续的运算操作有一定得影响,所以在实现过程中加了一道if语句来进行判定。
int r=1,t,x=numerator,y=denominator;
if(x>y){t=x;x=y;y=t;}
while(r!=0)
{
r=y%x;
y=x;
x=r;
}
numerator=numerator/y;
denominator=denominator/y;
if(denominator<0)
{
denominator=-denominator;
numerator=-numerator;
}
关于答案的验证问题的初尝试
因为我们输出形式的结果分为两种情况,整除情况的验证简单,但是如果结果出现分数的形式,就遇到int类型的分子+'/'+int类型的分母,这使得检验起来不太好实现,因为就答案的输入往往不能够实现上述的简单输入验证,所以这个问题有些困扰。
我个人有一个想法就是通过转换成字符串的结果,再由用户输入一串字符串来进行匹配检验,但这一步的实现还没有达到,仍需进一步的解决才好。
Part two 调度场算法的学习
以下是我和我的队友一起学习的情况,因为我们原本设计的算法在判断符号的顺序上只能够从左到右依次进行,并且需要设计者考虑到多种情况的不同处理方法,显然不够方便,但是调度场算法却能够很好的解决符号优先级以及先后的运算顺序,我们还不能够实现代码的写就,所以代码的编写我们求助于另一位有相关学习的同学,但大致的原理与运行都已经能够理解与运用。
主要实现的第一步是将原本的式子由中缀形式转为后缀的形式,数字与符号的排列得到重新的设定,这一步是为第二步中后缀形式的计算做准备。而第二步的实现,则通过判断字符优先以后对数字进行处理。这两种形式的实现都有涉及到stark以及string。(算法与目的实现的匹配还未能做到,却已经感受到了这种算法的独到之处)
void transform(string infix,char postfix[]) //中缀表达式转为后缀表达式
{
stack <char> sign;
int i=0,j=0;
while (i<infix.size())
{
if ((infix[i]>='0')&&(infix[i]<='9')) //判断数字
{
while ((infix[i]>='0')&&(infix[i]<='9'))
{
postfix[j]=infix[i];
i++;
j++;
}
postfix[j]='!'; //标识单个整数,为了不使得数字混排无法一一识别
j++;
}
if ((infix[i]=='+')||(infix[i]=='-')) //判断'+'、'-'
{
while (!sign.empty())
{
postfix[j]=sign.top();
j++;
sign.pop();
}
sign.push(infix[i]);
}
if (infix[i]=='*'||infix[i]=='/') //判断'*'、'/'
{
while ((!sign.empty())&&((sign.top()=='*')||(sign.top()=='/')))
{
postfix[j]=sign.top();
j++;
sign.pop();
}
sign.push(infix[i]);
}
i++;
}
while (!sign.empty()) //转出符号栈中剩余的运算符
{
postfix[j]=sign.top();
j++;
sign.pop();
}
postfix[j]='\0'; //补上一个终止符
}
//计算后缀表达式的值
int figure[MAX]; // 开一个存放运算操作的数栈
int calculate(string infix)
{
int i=0,point=-1;
int Numerator=1,Denominator=1;
char postfix[MAX];
transform(infix,postfix);
while (postfix[i]!='\0')
{
if (postfix[i]>='0'&&postfix[i]<='9')
{
double k=0;
while (postfix[i]>='0'&&postfix[i]<='9')
{
k=10*k+postfix[i]-'0';
i++;
}
point++;
figure[point]=k;
}
else
{
point--;
switch (postfix[i])
{
case '+':figure[point]=figure[point]+figure[point+1];break;
case '-':figure[point]=figure[point]-figure[point+1];break;
case '*':figure[point]=figure[point]*figure[point+1];break;
case '/':figure[point]=figure[point]/figure[point+1];break;
}
}
i++;
}
}
在学习的过程中,还学会了一种类型转换的实用技能,通过字符串流来进行实现
string str,s;
while(k<=3) //对格式进行转换,实现字符串来存储数据
{
stringstream temp;
temp << d[k];
temp >>s;
str+=s;
temp.clear();
k++;
if(i<=2)
{
stringstream temp;
temp <<char(c[i]);
temp >> s;
str+=s;
temp.clear(); //在下一次操作以前,需要将其清除
i++;
}
}
谢谢大家的观赏,以上就是我和我的小伙伴一起学习一起研究的收获以及感悟,未解决的 问题还在商榷,希望不足的地方还能够得到大家的指点与帮助。
说实话我的编程能力不够扎实,但我还在努力,菜鸡小豪的程序员之路还在继续中......