zoukankan      html  css  js  c++  java
  • 洛谷 P1022 计算器的改良 题解

    祭!!!

    至今刷题最大量代码(163行)

    不过代码不难理解

    我的思路呢,大致如下↓↓↓

    将首项和末项以及符号间的单项提取出来(用 substr 函数实现),进行移项(统一将一次项移到左边,常数项移到右边)

    再把常数和&&系数和相除

    完成这样的操作是个很繁琐的过程

    于是我将问题分解写了几个函数


    one

    确定该方程的未知数符号

    char find_char()//查找该方程的未知数 
    {
        int i;
        for(i=0;i<len;i++)//len是全局变量 
        {
            if(s[i]>='a'&&s[i]<='z')
            return s[i];
        }
    }

     two

    将等号的位置记录下来,以便操作

    int find_eq()//找到"="的位置 
    {
        int i;
        for(i=0;i<len;i++)//len是全局变量
        {
            if(s[i]=='=')
            return i;
        }
    }

    three

    将一个字符串转为整数

    int get_shu(string s)//将一个字符串转为整数 
    {
        int i,ans=0;
        for(i=0;i<s.size();i++)
        {
            ans*=10;
            ans+=(int)s[i]-'0';
        }
        return ans;    
    }

    four

    判断是否是未知项   说白了,就是判断提取出的子串中有无字母

    bool judge(string s)//判断是否是一次项 
    {
        int i;
        for(i=0;i<s.size();i++)
        {
            if(s[i]==c)
            return true;
        }
        return false;
    }

    five

    最核心的计算(别看代码长,其实是对称的)

    void heart(int f,int b)//计算 
    {
        string a=s.substr(f,b-f+1);
        //s.substr(a,b):在字符串s的第a位截取b个字符组成的子串 
        bool p=judge(a);
        if(p)//一次项(含未知项) 
        {
            if(b<=eq)//在等号左边 
            {
                if(a.size()==1)//要考虑系数为一而省略的情况 
                {
                  if(s[f-1]=='-')
                  xishu--;
                  else xishu++;
                }
                
                if(f==0) 
                    xishu+=get_shu(s.substr(f,b));//f是0,故b-f=b 
                else
                if(s[f-1]=='-')
                xishu-=get_shu(s.substr(f,b-f)); 
                else xishu+=get_shu(s.substr(f,b-f));
            }
            else//在等号右边 
            {
                if(a.size()==1)
               {
                  if(s[f-1]=='-')
                  xishu++;
                  else xishu--;
               }
                if(f==eq+1)
                xishu-=get_shu(s.substr(f,b-f));
                else
                if(s[f-1]=='-')
                xishu+=get_shu(s.substr(f,b-f));
                else xishu-=get_shu(s.substr(f,b-f));
            }
        }
        
        
        
        else//常数 
        {
               if(b<=eq)//在等号左边
            {
                if(f==0) 
                changshu-=get_shu(s.substr(f,b+1));//与前稍有不同 
                else
                if(s[f-1]=='-')
                changshu+=get_shu(s.substr(f,b-f+1));
                else changshu-=get_shu(s.substr(f,b-f+1));
            }
            
            else//在等号右边
            {
                if(f==eq+1)
                    changshu+=get_shu(s.substr(f,b-f+1));
                else
                if(s[f-1]=='-')
                changshu-=get_shu(s.substr(f,b-f+1));
                else changshu+=get_shu(s.substr(f,b-f+1));
            }
        }
    }

    那就上总体代码吧

    #include<bits/stdc++.h>
    using namespace std;
    string s;
    double ans;
    int len,i,eq;//eq为"="位置 
    char c;
    int xishu,changshu;//系数,常数^_^ 
    
    char find_char()//查找该方程的未知数 
    {
        int i;
        for(i=0;i<len;i++)//len是全局变量 
        {
            if(s[i]>='a'&&s[i]<='z')
            return s[i];
        }
    }
    
    int find_eq()//找到"="的位置 
    {
        int i;
        for(i=0;i<len;i++)//len是全局变量
        {
            if(s[i]=='=')
            return i;
        }
    }
    
    int get_shu(string s)//将一个字符串转为整数 
    {
        int i,ans=0;
        for(i=0;i<s.size();i++)
        {
            ans*=10;
            ans+=(int)s[i]-'0';
        }
        return ans;    
    }
    
    bool judge(string s)//判断是否是一次项 
    {
        int i;
        for(i=0;i<s.size();i++)
        {
            if(s[i]==c)
            return true;
        }
        return false;
    }
    
    
    
    void heart(int f,int b)//计算 
    {
        string a=s.substr(f,b-f+1);
        //s.substr(a,b):在字符串s的第a位截取b个字符组成的子串 
        bool p=judge(a);
        if(p)//一次项(含未知项) 
        {
            if(b<=eq)//在等号左边 
            {
                if(a.size()==1)//要考虑系数为一而省略的情况 
                {
                  if(s[f-1]=='-')
                  xishu--;
                  else xishu++;
                }
                
                if(f==0) 
                    xishu+=get_shu(s.substr(f,b));//f是0,故b-f=b 
                else
                if(s[f-1]=='-')
                xishu-=get_shu(s.substr(f,b-f)); 
                else xishu+=get_shu(s.substr(f,b-f));
            }
            else//在等号右边 
            {
                if(a.size()==1)
               {
                  if(s[f-1]=='-')
                  xishu++;
                  else xishu--;
               }
                if(f==eq+1)
                xishu-=get_shu(s.substr(f,b-f));
                else
                if(s[f-1]=='-')
                xishu+=get_shu(s.substr(f,b-f));
                else xishu-=get_shu(s.substr(f,b-f));
            }
        }
        
        
        
        else//常数 
        {
               if(b<=eq)//在等号左边
            {
                if(f==0) 
                changshu-=get_shu(s.substr(f,b+1));//与前稍有不同 
                else
                if(s[f-1]=='-')
                changshu+=get_shu(s.substr(f,b-f+1));
                else changshu-=get_shu(s.substr(f,b-f+1));
            }
            
            else//在等号右边
            {
                if(f==eq+1)
                    changshu+=get_shu(s.substr(f,b-f+1));
                else
                if(s[f-1]=='-')
                changshu-=get_shu(s.substr(f,b-f+1));
                else changshu+=get_shu(s.substr(f,b-f+1));
            }
        }
    }
    
    
    int main()
    {
        int ft,bd;
        cin>>s;
        len=s.size();
        c=find_char();
        eq=find_eq();
        
        ft=0; 
        for(i=0;i<=eq;i++)
        {
            if(s[i]=='+'||s[i]=='-'||i==eq)
            {
                bd=i-1;
                heart(ft,bd);
                ft=i+1;
            }
        }
        //等号左右分开操作 
        ft=eq+1; 
        for(i=eq+1;i<=len-1;i++)
        {
            if(s[i]=='+'||s[i]=='-')
            {
                bd=i-1;
                heart(ft,bd);
                
                ft=i+1;
            }
        }
        heart(ft,i-1);//处理最后一项 
    
        if(changshu==0) 
        {
            cout<<c<<"=0.000";
            return 0;
        }
        ans=(double)changshu/xishu;
        cout<<c<<"=";
        printf("%.3f",ans);
        return 0;
    }

    好吧,是有点长,模拟题嘛

  • 相关阅读:
    [ERR] Node 10.211.55.8:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    PAT A1137 Final Grading (25 分)——排序
    PAT A1136 A Delayed Palindrome (20 分)——回文,大整数
    PAT A1134 Vertex Cover (25 分)——图遍历
    PAT A1133 Splitting A Linked List (25 分)——链表
    PAT A1132 Cut Integer (20 分)——数学题
    PAT A1130 Infix Expression (25 分)——中序遍历
    PAT A1142 Maximal Clique (25 分)——图
    PAT A1141 PAT Ranking of Institutions (25 分)——排序,结构体初始化
    PAT A1140 Look-and-say Sequence (20 分)——数学题
  • 原文地址:https://www.cnblogs.com/zhouzhihao/p/10367004.html
Copyright © 2011-2022 走看看