[普及/提高-]P1022 计算器的改良

Xiaoma 程序设计 2020-03-01



题目链接:https://www.luogu.com.cn/problem/P1022


思路分析


观察输入的格式,不难发现是一个个的字符串,所以对于输入的东西我们要用字符串先把它存储起来,再进行后面的操作。


这是一个解一元一次方程的计算器,可以想一下假如给我们一个一元一次方程,要解出它的解,我们进行的处理是不是将变量放在等号的一边,常数放在等号的另一边?同样的,这种思维不算太抽象,是可以放在计算机里操作的。


因为是一元一次方程,所以变换成最后的形式应该是: ax=b ,那么现在的问题就是要得到a和b。现在更加细化一下方程变换过程,等号左边的自变量系数不变,而等号右边的自变量需要移到左边去,那么就是左边自变量的系数和减去右边自变量的系数,同样的,对于常数也是一样的,只不过变成了右边不变,减去左边而已。(就是平时我们在解方程的过程,自变量移到左边,常数移到右边的过程)


要得到a和b,还需要确定原方程中自变量系数和各个常数才行,我们先将每一个数字进行独立化。对于自变量的系数,我们可以发现有个标志性的东西,那就是自变量,一个字母而非数字。那么,如果数字后面带有字母,那就是自变量系数,否则就是常数。当然,在确定每一组数字时,还需要借助方程中的“+”、“-”、“=”来进行分隔,比如:12+25 在检查时一开始得到的数字是12,后来遇到了“+”号,显然这个数字到此为止了,就立刻把它独立出来,然后再重新获得下一个新的数字,即25。


好吧,上代码了。


代码


#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int main(){
    char fc[100];             //存储方程
    char wzs;                   //自变量的字母
    cin>>fc;
    for(int i=0;i<100;i++)                 //检查并确定自变量字母
        if(fc[i]>='A'&&fc[i]<='Z'||fc[i]>='a'&&fc[i]<='z'){
            wzs=fc[i];
            break;
        }
    fc[strlen(fc)]='=';               //用于处理结束前的最后一个数据
    int sz=0,zm;
    double lf=0,rgt=0;                     //lf存放自变量系数  rgt存放常数
    int coun1,coun2,fh=1,sta=0,dh=1;  //fh用于判断数字的符号,dh用于判断当前光标检查位置
    for(int i=0;i<strlen(fc);i++){           //sta用于判断该数是自变量系数还是常数
        if(fc[i]=='='){                      //遇到“=”
            if(sta==0) rgt+=(-1*fh)*sz*dh;
            if(sta==1)
                if(sz==0) lf+=fh*dh;
                else lf+=fh*sz*dh;
            sz=0;
            sta=0;
            dh=-1;
            fh=1;
        }
        if(fc[i]=='-'){                   //遇到“-”
            if(sta==0) rgt+=(-1*fh)*sz*dh;
            if(sta==1)
                if(sz==0) lf+=fh*dh;
                else lf+=fh*sz*dh;
            sz=0;
            sta=0;
            fh=-1;
        }
        if(fc[i]=='+'){                //遇到“+”
            if(sta==0) rgt+=(-1*fh)*sz*dh;
            if(sta==1)
                if(sz==0) lf+=fh*dh;
                else lf+=fh*sz*dh;
            sz=0;
            sta=0;
            fh=1;
        }
        if(fc[i]<='9'&&fc[i]>='0') sz=sz*10+fc[i]-'0';           //获得每一个数字
        if(fc[i]==wzs) sta=1;
    }
    printf("%c=%.3f",wzs,rgt/lf);
    return 0;
}


其实代码中有很多重复的部分,只是其中有某些细节的地方不一样,目前只会函数重载和了解一点点运算符重载,而这个东西能不能用重载我不知道,不过应该是有办法可以进一步简化的,代码行数多了点,但时间复杂度应该不会变吧?。。

PREV
[普及-]P1042 乒乓球
NEXT
回溯法 —— 八皇后问题

评论(0)

发布评论