CSP 化学方程式 50分

没有考虑括号嵌套,TODO:重合的太多了,代码风格得改

#include <iostream>
#include <unordered_map>
#include <cstring>
#include <vector>

using namespace std;

// 对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

int n;
string str;
string l,r;
unordered_map<string,int> lefts,rights; // 不能使用left,right
vector<string> elem;

string a,b;
int xishu;

void consult_l(string l)
{
    elem.clear(); // 清空
    // find只能是首次索引,对于多个值,只好费空间了,找不到就会返回-1
    int k = l.find("+");
    if(k == -1)
    {
        elem.push_back(l);
    }
    int f = 0;
    while(k != -1)
    {
        a = l.substr(0,k);
        elem.push_back(a);
        l = l.substr(k + 1); // 后面需要继续处理的
        // cout << l << endl; 
        k = l.find("+");
        f = 1;
    }
    if(f)   elem.push_back(l);
    
    for(auto e:elem)
    {
        // cout << e << endl; 
        // 处理系数
        if('A' <= e[0] && e[0] <= 'Z') xishu = 1;
        else // 找到多少个是数字
        {
            int i;
            for(i=0;i < (int)e.size();i++)
            {
                if('A' <= e[i] && e[i] <= 'Z') break;
            }
            xishu = atoi(e.substr(0,i).c_str());
            // cout << xishu << endl;
            e = e.substr(i); // 去除系数后的化学式
        }
        
        // 开始提取
        // 判断是一个大写字母还是大写字母+小写字母
        // TODO:处理方式基本相同,冗余代码太多了
        while(e.size() > 0)
        {
            if('a' <= e[1] && e[1] <= 'z') // 是大写+小写的 
            {
                int xi = 0;//这个系数也可能大于10。两位数
                string e1 = e.substr(0,2);
                if(e.size() > 2)
                {
                    e = e.substr(2);
                    // cout << e << endl;
                    if('A' <= e[0] && e[0] <= 'Z')  xi = 1;
                    else
                    {
                        int i;
                        for(i=0;i < (int)e.size();i++)
                        {
                            if('A' <= e[i] && e[i] <= 'Z') break;
                        }
                        xi = atoi(e.substr(0,i).c_str());
                        // cout << xishu << endl;
                        e = e.substr(i); // 去除系数后的化学式
                    }
                }
                else    xi = 1,e = "";
                
                lefts[e1] += xishu*xi;
            }
            else // 大写字母 
            {
                int xi = 0;
                string e1 = e.substr(0,1);
                if(e.size() > 1)
                {
                    e = e.substr(1);
                    if('A' <= e[0] && e[0] <= 'Z')
                    {
                        xi = 1;
                    }
                    else
                    {
                        int i;
                        for(i=0;i < (int)e.size();i++)
                        {
                            if('A' <= e[i] && e[i] <= 'Z') break;
                        }
                        xi = atoi(e.substr(0,i).c_str());
                        // cout << xishu << endl;
                        e = e.substr(i); // 去除系数后的化学式
                    }
                }
                else    xi = 1,e = "";
                // cout << e1 << " "<< xishu*xi << endl;
                lefts[e1] += xishu*xi;
            }
        }
    }
    
}

void consult_r(string& r)
{
    elem.clear(); // 清空
    int k = r.find("+");
    if(k == -1)
    {
        elem.push_back(r);
    }
    int f = 0;
    while(k != -1)
    {
        a = r.substr(0,k);
        elem.push_back(a);
        r = r.substr(k + 1); 
        k = r.find("+");
        f = 1;
    }
    if(f == 1) elem.push_back(r);
    
    
    for(auto e:elem)
    {
        // cout << e << endl; 
        if('A' <= e[0] && e[0] <= 'Z') xishu = 1;
        else 
        {
            int i;
            for(i=0;i < (int)e.size();i++)
            {
                if('A' <= e[i] && e[i] <= 'Z') break;
            }
            xishu = atoi(e.substr(0,i).c_str());
            e = e.substr(i);
        }
        
        while(e.size() > 0)
        {
            if('a' <= e[1] && e[1] <= 'z') // 是大写+小写的 
            {
                int xi = 0;//这个系数也可能大于10。两位数
                string e1 = e.substr(0,2);
                if(e.size() > 2)
                {
                    e = e.substr(2);
                    // cout << e << endl;
                    if('A' <= e[0] && e[0] <= 'Z')  xi = 1;
                    else
                    {
                        int i;
                        for(i=0;i < (int)e.size();i++)
                        {
                            if('A' <= e[i] && e[i] <= 'Z') break;
                        }
                        xi = atoi(e.substr(0,i).c_str());
                        e = e.substr(i); // 去除系数后的化学式
                    }
                }
                else    xi = 1,e = "";
                
                rights[e1] += xishu*xi;
            }
            else // 大写字母 
            {
                int xi = 0;
                string e1 = e.substr(0,1);
                if(e.size() > 1)
                {
                    e = e.substr(1);
                    if('A' <= e[0] && e[0] <= 'Z')
                    {
                        xi = 1;
                    }
                    else
                    {
                        int i;
                        for(i=0;i < (int)e.size();i++)
                        {
                            if('A' <= e[i] && e[i] <= 'Z') break;
                        }
                        xi = atoi(e.substr(0,i).c_str());
                        // cout << xishu << endl;
                        e = e.substr(i); // 去除系数后的化学式
                    }
                }
                else    xi = 1,e = "";
                rights[e1] += xishu*xi;
            }
        }
    }

}

int main()
{
    cin >> n;
    while(n--)
    {
        // 每次map需要清空
        // memset(lefts,0,sizeof(lefts));
        // memset(rights,0,sizeof(rights));
        lefts.clear();
        rights.clear();
        cin >> str;
        int k = str.find("=");// 遇到等号分两边处理
        // cout << k << endl;
        l = str.substr(0,k);
        r = str.substr(k + 1);
        consult_l(l);// 需要用map函数来处理
        consult_r(r);

        int flag = 1;

        for(auto x:lefts)
        {
            string k1 = x.first;
            int v1 = x.second;
            if(rights[k1] != v1)
            {
                cout << "N" << endl;
                flag = 0;
                break;
            }
        }
        if(flag)    cout << "Y" << endl;
    }
    
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值