Skip to content
Snippets Groups Projects
main.cpp 1.81 KiB
Newer Older
Florian Steinkamp's avatar
Florian Steinkamp committed
#include <iostream>
#include <optional>
#include <stack>
#include <stdexcept>
#include <climits>
#include <unordered_map>
#include <iterator>

std::stack<int> stack;

int subtract(int a, int b) { 
        return b - a; 
}
int multiply(int a, int b) { 
       return a * b; 
}
/*
 * Divides integer b from integer a, throwing an exception when b is zero
 */
int divide(int a, int b) {
Florian Steinkamp's avatar
Florian Steinkamp committed
	if (b == 0) {
		throw std::invalid_argument("Tried to divide by 0.");
Florian Steinkamp's avatar
Florian Steinkamp committed
	}
	return a / b;
}

std::unordered_map<char, decltype(&plus)> map {
	{'+', add},
	{'-', subtract},
	{'*', multiply},
	{'/', divide}
Florian Steinkamp's avatar
Florian Steinkamp committed
};

int evaluate(const std::string &s) {
	int a,b;
	std::unordered_map<char, decltype(&plus)>::iterator iter;
	for (char c : s) {
		if (std::isdigit(c)) {
			stack.push(c - '0');
		} else {
			if (stack.size() >= 2 ) {
				iter = map.find(c);
				if (iter != map.end()) {
					a = stack.top();
					stack.pop();
					b = stack.top();
					stack.pop();
					stack.push(iter->second(b, a));
				} else {
					throw std::invalid_argument("Invalid character found.");
Florian Steinkamp's avatar
Florian Steinkamp committed
				}
			} else {
				throw std::invalid_argument("Invalid number of digits.");
Florian Steinkamp's avatar
Florian Steinkamp committed
			}
		}
	}
	if (stack.size() > 1 || stack.size() == 0) {
		throw std::invalid_argument("Invalid input.");
Florian Steinkamp's avatar
Florian Steinkamp committed
	}
	return stack.top();
}

int main() {
  std::string user_input;
  std::cin >> user_input;

  if (user_input.empty()) {
    std::cout << "Empty input\n";
    return 1; 
  }
Florian Steinkamp's avatar
Florian Steinkamp committed

  std::cout << "User input is \"" << user_input << "\"\n";

	int result = INT_MAX;

	try {
		result = evaluate(user_input);
	} catch (const std::exception &e) {
		std::cout << e.what();
	}
	if (result != INT_MAX) {
		std::cout << "Result is: " << result << '\n';		
	}
    
}