Cod sursa(job #3152133)

Utilizator Summer05Cocut Alexandru Summer05 Data 24 septembrie 2023 03:19:25
Problema Evaluarea unei expresii Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 8.59 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <climits>
#include <iomanip>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <iterator>
#include <vector>
#include <algorithm>
#include <numeric>
#include <queue>
#include <stack>
#include <bitset>
#include <functional>
#include <utility>
#include <cmath>
#include <string>
#include <deque>
#include <array>
#include <tuple>
#include <cstring>
#include <ctime>
#include <random>
#include <chrono>
///#include <windows.h>

#pragma GCC optimize("fast-math")

#define ll long long
#define ld long double
#define pll pair<ll, ll>
#define psi pair<short int, short int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define all(x) (x).begin() + 1, (x).end()
#define all0(x) (x).begin(), (x).end()
#define allrev(x) (x).rbegin(), (x).rend() - 1
#define allrev0(x) (x).rbegin(), (x).rend()
#define println(thing) cout << thing << '\n'
#define yes println("YES")
#define no println("NO")
#define maybe println("MAYBE")
#define mda println("/////////////////")
#define msb(x) ((x) == 0 ? 0 : (1 << (64 - __builtin_clzll(x) - 1)))
#define lsb(x) ((x) & (-x))

using namespace std;

mt19937_64 rng(chrono :: steady_clock :: now().time_since_epoch().count());

const size_t fixed_random = rng();

clock_t start_time = clock(), end_time;

ll random_seed(ll modulo) {
    return rng() % modulo;
}

template <typename T>
inline void hash_combine(size_t& seed, const T& value) {
    seed ^= hash<T>{}(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

struct pair_hash {
    template <typename T1, typename T2>
    size_t operator () (const pair<T1, T2>& p) const {
        size_t seed = fixed_random;

        hash_combine(seed, p.first);
        hash_combine(seed, p.second);

        return seed;
    }
};

struct normal_hash {
    template <typename T>
    size_t operator () (const T& p) const {
        size_t seed = fixed_random;

        hash_combine(seed, p);

        return seed;
    };
};

template <typename unordered_Map>
void optimize_map(unordered_Map& M) {
    M.reserve(1024);
    M.max_load_factor(0.5);
}

template <typename T1, typename T2>
istream& operator >> (istream& in, pair<T1, T2>& p) {
    in >> p.first >> p.second;
    return in;
}

template <typename T1, typename T2>
ostream& operator << (ostream& out, pair<T1, T2>& p) {
    out << p.first << ' ' << p.second;
    return out;
}

/// for bitset bits
template <typename T1, typename T2> T1 operator ^= (T1 t1, T2 t2) {t1 = t1 ^ t2; return t1;}
template <typename T1, typename T2> T1 operator |= (T1 t1, T2 t2) {t1 = t1 | t2; return t1;}
template <typename T1, typename T2> T1 operator &= (T1 t1, T2 t2) {t1 = t1 & t2; return t1;}

const ll NMX = (ll) 1e7;
const ll MOD = (ll) 1e9 + 7;
const ll INF = (ll) 1e17;

ll binExp(ll base, ll exp) {
    ll P = 1;
    for (ll bit = 1; bit <= exp; bit <<= 1) {
        if (exp & bit)
            P = (P * base) % MOD;
        base = (base * base) % MOD;
    }
    return P;
}

inline ll modInv(ll x) {
    return binExp(x, MOD - 2);
}

ll test_case = 0;

void solve(ll testcase)
{
    string s;
    cin >> s;

    function<string(ll&)> int_to_string = [&](ll &x) {
        string to_return = "";
        if (x < 0) {
            to_return += '-';
            x = llabs(x);
        }
        string temp = "";
        if (x == 0) {
            temp += '0';
        }
        while (x != 0) {
            char ch = char(x % 10 + '0');
            temp += ch;
            x /= 10;
        }
        reverse(all0(temp));
        to_return += temp;
        return to_return;
    };

    function<string(string&)> evaluate_small = [&](string &expression) {
        stack<char> stk_temp;
        for (ll i = 0; i < (ll) expression.size(); i++) {
            if (!stk_temp.empty() && (stk_temp.top() == '+' || stk_temp.top() == '-')) {
                ll second_number = 0, j;
                for (j = i; j < (ll) expression.size(); j++) {
                    if (expression[j] < '0' || expression[j] > '9') {
                        break;
                    }
                    else {
                        second_number = second_number * 10 + expression[j] - '0';
                    }
                }
                i = j - 1;
                char operation = stk_temp.top();
                stk_temp.pop();
                ll first_number = 0, p = 1;
                while (!stk_temp.empty() && stk_temp.top() != '+' && stk_temp.top() != '-') {
                    first_number += p * (stk_temp.top() - '0');
                    p *= 10;
                    stk_temp.pop();
                }
                if (!stk_temp.empty() && stk_temp.top() == '-') {
                    stk_temp.pop();
                    first_number = -first_number;
                }
                ll value;
                if (operation == '+') {
                    value = first_number + second_number;
                }
                else {
                    value = first_number - second_number;
                }
                string temp = int_to_string(value);
                for (ll j = 0; j < (ll) temp.size(); j++) {
                    stk_temp.push(temp[j]);
                }
            }
            else {
                stk_temp.push(expression[i]);
            }
        }

        string temp = "";
        while (!stk_temp.empty()) {
            temp += stk_temp.top();
            stk_temp.pop();
        }
        reverse(all0(temp));

        return temp;
    };

    function<string(string&)> evaluate_big = [&](string &expression) {
        stack<char> stk_temp;
        for (ll i = 0; i < (ll) expression.size(); i++) {
            if (!stk_temp.empty() && (stk_temp.top() == '*' || stk_temp.top() == '/')) {
                ll second_number = 0, j;
                for (j = i; j < (ll) expression.size(); j++) {
                    if (expression[j] < '0' || expression[j] > '9') {
                        break;
                    }
                    else {
                        second_number = second_number * 10 + expression[j] - '0';
                    }
                }
                i = j - 1;
                char operation = stk_temp.top();
                stk_temp.pop();
                ll first_number = 0, p = 1;
                while (!stk_temp.empty() && stk_temp.top() != '+' && stk_temp.top() != '-') {
                    first_number += p * (stk_temp.top() - '0');
                    p *= 10;
                    stk_temp.pop();
                }
                if (!stk_temp.empty() && stk_temp.top() == '-') {
                    stk_temp.pop();
                    first_number = -first_number;
                }
                ll value;
                if (operation == '*') {
                    value = first_number * second_number;
                }
                else {
                    value = first_number / second_number;
                }
                string temp = int_to_string(value);
                for (ll j = 0; j < (ll) temp.size(); j++) {
                    stk_temp.push(temp[j]);
                }
            }
            else {
                stk_temp.push(expression[i]);
            }
        }

        string temp = "";
        while (!stk_temp.empty()) {
            temp += stk_temp.top();
            stk_temp.pop();
        }
        reverse(all0(temp));
        temp = evaluate_small(temp);

        return temp;
    };

    stack<char> stk;

    for (ll i = 0; i < (ll) s.size(); i++) {
        if (s[i] == ')') {
            string temp = "";
            while (stk.top() != '(') {
                temp += stk.top();
                stk.pop();
            }
            stk.pop();
            reverse(all0(temp));
            temp = evaluate_big(temp);
            for (ll j = 0; j < (ll) temp.size(); j++) {
                stk.push(temp[j]);
            }
        }
        else {
            stk.push(s[i]);
        }
    }

    string temp = "";
    while (!stk.empty()) {
        temp += stk.top();
        stk.pop();
    }
    reverse(all0(temp));
    temp = evaluate_big(temp);

    return cout << temp << '\n', void();
}

int main(void)
{
    freopen("evaluare.in", "r", stdin);
    freopen("evaluare.out", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

    ///cout << fixed << setprecision(20);

    ///ll tt; cin >> tt; while (tt--)
       solve(++test_case);
    \

    return 0;
}

/**

///

**/