落谷 p1022计算器的改良 题目解析

题目链接:

https://www.luogu.org/problem/show?pid=P1022

基本思路:此题的主要难点在于字符的处理,我刚开始的思路是全部输入完成后在进行计算,但是发现,不对,因为我所写的程序是按照样例来写的,但是样例(6a-5+1=2a)给定的数字都是一个字符,所以不需要对数字进行累加,但是当我发现如果样例是(67a-5+1=24a)时,我的方法就不对了。果断放弃我的想法,然后开始思考一个一个字符的处理。首先定义两个变量a1,a2用来分别储存常数项的和和变量的系数的和,最后结果就是-b1/a1;

代码如下:

#include<bits/stdc++.h>
using namespace std;
char op;
char op1;
int opp=1;//表示等号左边还是右边。左边:1,右边:-1。
int a1=0;//储存系数和
int b1=0;//储存常数项的和
int cur=0;//累加计算每一个系数或者每一个常数项
double jieguo;//结果
int sign=1;//表示正负号
int main()
{
    op=getchar();
    int c=1;
    while (1)
    {
        if(c==1&&op>='a'&&op<='z')//必须得加这一个判断,因为当第一个字符就是变量时,变量前面的系数是一,
        {
            a1=1;//此时必须得让a1加1,以保存系数
            op=getchar();//如果没有上面那个判断,循环进来后直接到第三个判断,此时cur等于0,a1等于0,没有加上a前面的1,显然不对
            c++;
            continue;
        }
        c++;
        if(op>='0'&&op<='9')//这个判断是用来计算常数项或系数的
        {
             cur=cur*10+sign*(op-'0')*opp;//当两个数字字符连在一块时,这样计算是正确的,sign表示正负号,当该数字字符前面
        }//是一个负号时,sign会变成-1,下面代码有,此时算出来的系数或常数项是负的,正确。
        else if(op>='a'&&op<='z')
        {
            op1=op;//记录变量,最后输出时用
            a1+=cur;//累加变量前面的系数
            cur=0;//如果遇到一个变量,说明变量前面的系数已经算完了,此时把cur定为0,来计算下面常数项或变量前面的系数
        }//这个变量前面系数和后面任意一个数没有任何关系
        else if(op=='-')
        {
            b1+=cur;//如果遇到减号,说明前面可能是一个常数项,并且已经计算完了,这时需要累加到b1里面,如果 负号前面是一个变量,不用管,因为上面一个判断已经把这个变量前面的系数累加到a1里去了
            sign=-1;//把符号弄成负的,因为负号后面如果是常数项,那么这个常数项必定是负的
            cur=0;//和上面cur=0的操作的解释是一样的。
        }
        else if(op=='+')
        {
            b1+=cur;//和负号的解释完全一样。
            sign=1;
            cur=0;
        }
        else if(op=='=')
        {
            b1+=cur;//如果遇到等于号,那么还是把常数项累加到b1中去,和正号,负号的解释一样
            opp=-1;//此时必须把opp设置为负的,因为我们在计算方程时,移项之后负号改变,这就相当于移项操作,把等号左边本来是正数的数变成负数,本来是负数的数变成正数
            cur=0;
            sign=1;//这个操作必须有,因为如果等号前面是一个负的常数项,等号后面是一个正的常数项,必须把sign设置为正的,以便来计算下面正的常数项的系数,如果没有这个操作,那么下面得到的常数项的系数负号就反了,因为sign为负,opp为负,负负得正(这是在等号右边,表达式显示的系数为正那么计算的结果必须为负,表达式显示的系数为负那么计算的结果必须为正),结果就不对了
        }          //如果还是不懂,用(6a+5-1=45+6a)例子来试试
        else
        {
            b1+=cur;//如果到达了这里,说明已经到结尾了,如果最后一个字符是字母,那么会进上面的判断条件,不会进这个,如果最后一个字符不是字母,那么就会进这个判断,把常数项累加到b1中
            break ;
        }
        op=getchar();
    }
    //cout<<a1<<" "<<b1<<endl;
    if(a1==0||b1==0)
        cout<<op1<<'='<<"0.000";
    else
    {
        jieguo=-(1.0*b1)/a1;//这里必须加一个负号,还是移项问题
        cout<<op1<<'=';
        printf("%.3f",jieguo);
    }

}


这题坑点很多,需要注意  呜呜呜

猜你喜欢

转载自blog.csdn.net/qq_40938077/article/details/80049376