Cod sursa(job #2357809)

Utilizator AntoniuFicAntoniu Ficard AntoniuFic Data 27 februarie 2019 19:01:52
Problema Evaluarea unei expresii Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.53 kb
#include <fstream>
#include <cstring>

using namespace std;

long long evalExpression(char stri[], int len){
    char str[100000];
    strncpy(str, stri, len);
    str[len]=0;
    for(int i=1; i<len; i++){
        if(str[i] == '-' && str[i-1] != '+')
        {
            char temp[100000];
            strcpy(temp, str+i);
            strcpy(str+i, "+");
            strcpy(str+i+1, temp);
            i++;
            len = strlen(str);
        }
    }
    int bracketPos = -1;
    int brackets = 0;
    int subPartLength = 0;
    for(int i=0; i<len; i++){
        if(str[i] == '('){
            if(bracketPos == -1)
                bracketPos = i;
            if(brackets>0)
                subPartLength++;
            brackets++;
        }
        else if(str[i] == ')'){
            brackets--;
            if(brackets>0)
                subPartLength++;
        }
        else if(bracketPos!=-1)
            subPartLength++;
        if(bracketPos != -1 && brackets == 0) {
            long long value = evalExpression(str+bracketPos+1, subPartLength), digits, aux = value;
            for(digits = 0; aux; aux/=10, digits++);
            for(int current = digits-1; current>=0; current--, value/=10){
                str[bracketPos+current]=char(value%10)+'0';
            }
            char temp[155];
            strcpy(temp, str+bracketPos+2+subPartLength);
            strcpy(str+bracketPos+digits, temp);
            len = strlen(str);
            i=bracketPos+digits;
            bracketPos = -1;
        }
    }
    bool currval = false, negx = false, negy = false;
    long long x=0, y=0, startPos1=0, startPos2=0;
    char sign = 0;
    for(int i=0; i<len; i++){
        if(strchr("+/*", str[i]) != NULL){
            long long value=-1;
            if(negx)
                x*=-1, negx = false;
            if(negy)
                y*=-1, negy = false;
            if(sign == '*')
                value=x*y;
            else if(sign == '/' && currval && y!=0)
                value=x/y;
            else if(sign == '/' && x!=0)
                value=y/x;
            sign = str[i];
            if(value != -1){
                int pos;
                if(currval)
                    pos = startPos2;
                else
                    pos = startPos1;
                int digits, aux = value;
                for(digits = 0; aux; aux/=10, digits++);
                if(value<0)
                    value*=-1, str[pos++] = '-';
                for(int current = digits-1; current>=0; current--, value/=10){
                    str[pos+current]=char(value%10)+'0';
                }
                char temp[155];
                strcpy(temp, str+i);
                strcpy(str+pos+digits, temp);
                i= pos-1;
                if(str[i] == '-')
                    i--;
                sign = 0;
                len = strlen(str);
            }
            if(!currval)
                y=0, startPos1 = i+1;
            else
                x=0, startPos2 = i+1;
            currval = !currval;
        }
        if(!currval && str[i] == '-')
            negx = true;
        else if(str[i] == '-')
            negy = true;
        if(!currval && isdigit(str[i]))
            x=x*10+(str[i]-'0');
        else if(isdigit(str[i]))
            y=y*10+(str[i]-'0');
    }
    long long value=-1;
    if(negx)
        x*=-1, negx = false;
    if(negy)
        y*=-1, negy = false;
    if(sign == '*')
        value=x*y;
    else if(sign == '/' && currval && y!=0)
        value=x/y;
    else if(sign == '/' && x!=0)
        value=y/x;
    if(value != -1) {
        int pos;
        if (currval)
            pos = startPos2;
        else
            pos = startPos1;
        int digits, aux = value;
        for (digits = 0; aux; aux /= 10, digits++);
        if(value<0)
            value*=-1, str[pos++] = '-';
        for (int current = digits - 1; current>=0; current--, value /= 10) {
            str[pos + current] = char(value % 10) + '0';
        }
        str[pos+digits] = 0;
    }
    len = strlen(str);
    x=0, y=0, sign=0, currval = false, startPos1 = 0, startPos2 = 0, negx = false, negy = false;
    for(int i=0; i<len; i++){
        if(strchr("+/*", str[i]) != NULL){
            value=-1;
            if(negx)
                x*=-1, negx = false;
            if(negy)
                y*=-1, negy = false;
            if(sign == '+')
                value=x+y;
            sign = str[i];
            if(value != -1){
                int pos;
                if(currval)
                    pos = startPos2;
                else
                    pos = startPos1;
                int digits, aux = value;
                for(digits = 0; aux; aux/=10, digits++);
                if(value<0)
                    value*=-1, str[pos++] = '-';
                for(int current = digits-1; current>=0; current--, value/=10){
                    str[pos+current]=char(value%10)+'0';
                }
                char temp[155];
                strcpy(temp, str+i);
                strcpy(str+pos+digits, temp);
                i= pos-1;
                if(str[i] == '-')
                    i--;
                sign = 0;
                len = strlen(str);
            }
            if(!currval)
                y=0, startPos1 = i+1;
            else
                x=0, startPos2 = i+1;
            currval = !currval;
        }
        if(!currval && str[i] == '-')
            negx = true;
        else if(str[i] == '-')
            negy = true;
        if(!currval && isdigit(str[i]))
            x=x*10+(str[i]-'0');
        else if(isdigit(str[i]))
            y=y*10+(str[i]-'0');
    }
    value=-1;
    if(negx)
        x*=-1, negx = false;
    if(negy)
        y*=-1, negy = false;
    if(sign == '+')
        value=x+y;
    if(value != -1){
        int pos;
        if(currval)
            pos = startPos2;
        else
            pos = startPos1;
        int digits, aux = value;
        for(digits = 0; aux; aux/=10, digits++);
        if(value<0)
            value*=-1, str[pos++] = '-';
        for(int current = digits-1; current>=0; current--, value/=10){
            str[pos+current]=char(value%10)+'0';
        }
        str[pos+digits]=0;
    }
    len = strlen(str);
    long long result = 0;
    bool neg = false;
    for(int i=0; i<len; i++){
        if(str[i] == '-')
            neg = true;
        else if(isdigit(str[i]))
            result= result*10 + str[i] - '0';
    }
    if(neg)
        result*=-1;
    return result;
}

int main() {
    ifstream f("evaluare.in");
    ofstream g("evaluare.out");
    char str[100000]="";
    f.getline(str, 100000);
    g<<evalExpression(str, strlen(str));
    return 0;
}