csp 201912-3 化学方程式

csp 201912-3 化学方程式

起因

感觉csp的第三题还有点意思,所以再作一道.

经过

看到这题,立马明白,
这是要我变成

人肉yacc

至于这是LL,LR(0),LR(1)我也没搞清楚.

结果

调了一会,调出来了.

#include <bits/stdc++.h>

using namespace std;

typedef map<string,int> Elem;

inline bool upper(char c) {
    
     return 'A'<=c&&c<='Z';}
inline bool lower(char c) {
    
     return 'a'<=c&&c<='z';}
inline bool digit(char c) {
    
     return '0'<=c&&c<='9';}

char s[1001];
int i;

Elem parseFormular();
string parseElement() {
    
    //OK!
    string ret;
    ret+=s[i++];
    if(lower(s[i]))ret+=s[i++];
    return ret;
}

int parseCoef() {
    
    //OK!
    int ret=0;
    while(digit(s[i]))ret*=10,ret+=s[i]-'0',++i;
    return ret;
}

Elem parseTerm() {
    
    
    Elem ret;
    string name;
    if(s[i]=='('){
    
    
        ++i;
        ret=parseFormular();
        assert(s[i++]==')');
    }
    else{
    
    
        assert(upper(s[i]));
        name=parseElement();
        ++ret[name];
    }
    return ret;
}

Elem parseFormular() {
    
    
    Elem ret,term;
    int coef;
    while(true){
    
    
        term=parseTerm();
        if(digit(s[i])){
    
    
            coef=parseCoef();
        }
        else coef=1;
        for(auto& i:term) ret[i.first]+=coef*i.second;
        if(s[i]=='='||s[i]=='\0'||s[i]=='+'||s[i]==')')break;
    }
    return ret;
}

Elem parseExpr() {
    
    
    Elem ret,formular;
    int coef;
    while(true){
    
    
        if(digit(s[i])){
    
    
            coef=parseCoef();
        }
        else coef=1;
        formular=parseFormular();
        for(auto& i:formular) ret[i.first]+=coef*i.second;
        if(s[i]=='='||s[i]=='\0'){
    
    
            break;
        }
        if(s[i]=='+')++i;
    }
    return ret;
}

bool checkEquation() {
    
    
    Elem l,r;
    l=parseExpr();
    assert(s[i++]=='=');
    r=parseExpr();
    for(auto& i:l)fprintf(stderr,"%dx%s ",i.second,i.first.c_str());
    fprintf(stderr,"\n");
    for(auto& i:r)fprintf(stderr,"%dx%s ",i.second,i.first.c_str());
    fprintf(stderr,"\n");
    return l==r;
}

int main() {
    
    
    ios::sync_with_stdio(false),cin.tie(0);
#ifdef debug
    freopen("test.in","r",stdin);
#endif
    int n;
    cin>>n;
    cin.getline(s,sizeof(s));
    for(int _=0;_<n;++_){
    
    
        i=0;
        cin.getline(s,sizeof(s));
        fprintf(stderr,"eq: %s\n",s);
        printf("%c\n",checkEquation()?'Y':'N');
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/agctXY/article/details/120093540
おすすめ