some programs!!
This commit is contained in:
1 parent
ed054247d5
commit
71f1022dea
38 files changed
+1037
-281
No files matched your search
@@ -0,0 +1,165 @@
|
||||
#include <iostream>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <cassert>
|
||||
|
||||
class Token {
|
||||
protected:
|
||||
std::variant<char, int> token_variant_;
|
||||
|
||||
public:
|
||||
explicit Token(char c) : token_variant_(c) {}
|
||||
explicit Token(int x) : token_variant_(x) {}
|
||||
|
||||
[[nodiscard]] bool is_operator() const {
|
||||
return std::holds_alternative<char>(token_variant_);
|
||||
}
|
||||
|
||||
[[nodiscard]] char get_operator() const {
|
||||
if (!is_operator()) { throw std::invalid_argument("Not an operator"); }
|
||||
return std::get<char>(token_variant_);
|
||||
}
|
||||
|
||||
[[nodiscard]] int get_number() const {
|
||||
if (is_operator()) { throw std::invalid_argument("Is an operator"); }
|
||||
return std::get<int>(token_variant_);
|
||||
}
|
||||
|
||||
[[nodiscard]] int get_priority() const {
|
||||
if (get_operator() == '+' || get_operator() == '-') { return 1; }
|
||||
if (get_operator() == '*' || get_operator() == '/') { return 2; }
|
||||
throw std::invalid_argument("Unknown priority");
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
[[nodiscard]] auto calc_operator(T1 a, T2 b) const {
|
||||
switch (get_operator()) {
|
||||
case '+': return a + b;
|
||||
case '-': return a - b;
|
||||
case '*': return a * b;
|
||||
case '/': return a / b;
|
||||
default: throw std::invalid_argument("Uncalculatable operator");
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(char c) const {
|
||||
if (!is_operator()) { return false; }
|
||||
return get_operator() == c;
|
||||
}
|
||||
|
||||
bool operator==(int x) const {
|
||||
if (is_operator()) { return false; }
|
||||
return get_number() == x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(T x) {
|
||||
return !(*this == x);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, Token token) {
|
||||
if (token.is_operator()) {
|
||||
os << token.get_operator();
|
||||
} else {
|
||||
os << '[' << token.get_number() << ']';
|
||||
}
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
using Expression = std::vector<Token>;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Expression& expression) {
|
||||
for (const auto& token : expression) {
|
||||
os << token;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
Expression parse_string(const std::string& str) {
|
||||
Expression expression;
|
||||
std::string temp_token;
|
||||
for (char c : str) {
|
||||
if (!(c >= '0' && c <= '9')) {
|
||||
if (!temp_token.empty()) {
|
||||
expression.emplace_back(std::stoi(temp_token));
|
||||
temp_token.clear();
|
||||
}
|
||||
expression.emplace_back(c);
|
||||
} else {
|
||||
temp_token += c;
|
||||
}
|
||||
}
|
||||
if (!temp_token.empty()) { expression.emplace_back(std::stoi(temp_token)); }
|
||||
return expression;
|
||||
}
|
||||
|
||||
Expression convert_to_postfix(const Expression& infix_expression) {
|
||||
Expression postfix_expression;
|
||||
std::stack<Token> operators;
|
||||
|
||||
for (const auto& token : infix_expression) {
|
||||
if (!token.is_operator()) {
|
||||
postfix_expression.push_back(token);
|
||||
continue;
|
||||
}
|
||||
if (token.get_operator() == '(') {
|
||||
operators.push(token);
|
||||
continue;
|
||||
}
|
||||
if (token.get_operator() == ')') {
|
||||
while (operators.top().get_operator() != '(') {
|
||||
postfix_expression.push_back(operators.top());
|
||||
operators.pop();
|
||||
}
|
||||
operators.pop();
|
||||
continue;
|
||||
}
|
||||
while (!operators.empty() && operators.top() != '('
|
||||
&& token.get_priority() <= operators.top().get_priority()) {
|
||||
postfix_expression.push_back(operators.top());
|
||||
operators.pop();
|
||||
}
|
||||
operators.push(token);
|
||||
}
|
||||
while (!operators.empty()) {
|
||||
postfix_expression.push_back(operators.top());
|
||||
operators.pop();
|
||||
}
|
||||
return postfix_expression;
|
||||
}
|
||||
|
||||
int calculate_postfix(const Expression& postfix_expression) {
|
||||
std::stack<int> numbers;
|
||||
for (const auto& token : postfix_expression) {
|
||||
if (!token.is_operator()) {
|
||||
numbers.push(token.get_number());
|
||||
continue;
|
||||
}
|
||||
int b = numbers.top();
|
||||
numbers.pop();
|
||||
int a = numbers.top();
|
||||
numbers.pop();
|
||||
numbers.push(token.calc_operator(a, b));
|
||||
}
|
||||
assert(numbers.size() == 1);
|
||||
return numbers.top();
|
||||
}
|
||||
|
||||
std::string s;
|
||||
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::cin >> s;
|
||||
while (std::cin >> s) {
|
||||
Expression infix_expression = parse_string(s);
|
||||
std::clog << infix_expression << std::endl;
|
||||
Expression postfix_expression = convert_to_postfix(infix_expression);
|
||||
std::cout << calculate_postfix(postfix_expression) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user