Advertisement
Mikhail-Podbolotov

Untitled

Apr 17th, 2025
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.77 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3.  
  4. // ===== Stack =====
  5. template <typename T>
  6. class Stack {
  7. private:
  8.     struct Node {
  9.         T data;
  10.         Node* next;
  11.         Node(const T& value, Node* nextNode = nullptr)
  12.             : data(value), next(nextNode) {
  13.         }
  14.     };
  15.  
  16.     Node* topNode;
  17.  
  18. public:
  19.     Stack() : topNode(nullptr) {}
  20.  
  21.     ~Stack() {
  22.         while (!isEmpty()) {
  23.             pop();
  24.         }
  25.     }
  26.  
  27.     void push(const T& value) {
  28.         topNode = new Node(value, topNode);
  29.     }
  30.  
  31.     void pop() {
  32.         if (isEmpty()) {
  33.             std::cerr << "Error: Stack is empty, cannot pop.\n";
  34.             return;
  35.         }
  36.         Node* temp = topNode;
  37.         topNode = topNode->next;
  38.         delete temp;
  39.     }
  40.  
  41.     T& top() {
  42.         if (isEmpty()) {
  43.             std::cerr << "Error: Stack is empty.\n";
  44.             std::exit(1);
  45.         }
  46.         return topNode->data;
  47.     }
  48.  
  49.     bool isEmpty() const {
  50.         return topNode == nullptr;
  51.     }
  52. };
  53.  
  54. // ===== Utils =====
  55. bool isNumber(const std::string& s) {
  56.     if (s.empty()) return false;
  57.     size_t start = 0;
  58.     if (s[0] == '-' && s.size() > 1) start = 1;
  59.     for (size_t i = start; i < s.size(); ++i)
  60.         if (s[i] < '0' || s[i] > '9') return false;
  61.     return true;
  62. }
  63.  
  64. int toInt(const std::string& s) {
  65.     int result = 0;
  66.     bool negative = false;
  67.     size_t i = 0;
  68.     if (s[0] == '-') { negative = true; i = 1; }
  69.     for (; i < s.size(); ++i) result = result * 10 + (s[i] - '0');
  70.     return negative ? -result : result;
  71. }
  72.  
  73. // ===== RPN Evaluation =====
  74. int evaluateRPN(const std::string& input) {
  75.     Stack<int> stack;
  76.     std::string token = "";
  77.  
  78.     for (size_t i = 0; i <= input.length(); ++i) {
  79.         char ch = (i < input.length()) ? input[i] : ' ';
  80.  
  81.         if (ch != ' ') {
  82.             token += ch;
  83.         }
  84.         else if (!token.empty()) {
  85.             if (isNumber(token)) {
  86.                 stack.push(toInt(token));
  87.             }
  88.             else if (token == "+" || token == "-" || token == "*" || token == "/") {
  89.                 if (stack.isEmpty()) return -999999; // Error code
  90.                 int b = stack.top(); stack.pop();
  91.                 if (stack.isEmpty()) return -999999;
  92.                 int a = stack.top(); stack.pop();
  93.  
  94.                 if (token == "+") stack.push(a + b);
  95.                 else if (token == "-") stack.push(a - b);
  96.                 else if (token == "*") stack.push(a * b);
  97.                 else if (token == "/") {
  98.                     if (b == 0) return -888888; // Деление на 0
  99.                     stack.push(a / b);
  100.                 }
  101.             }
  102.             else {
  103.                 std::cerr << "Unknown token: " << token << "\n";
  104.                 return -777777; // Некорректный токен
  105.             }
  106.             token = "";
  107.         }
  108.     }
  109.  
  110.     if (!stack.isEmpty()) {
  111.         int result = stack.top(); stack.pop();
  112.         if (!stack.isEmpty()) return -666666; // Stack not empty at end — ошибка
  113.         return result;
  114.     }
  115.  
  116.     return -555555; // Пустой ввод
  117. }
  118.  
  119. // ===== Stack Test =====
  120. void testStack() {
  121.     std::cout << "[Stack Test]\n";
  122.     Stack<int> s;
  123.     s.push(1);
  124.     s.push(2);
  125.     s.push(3);
  126.  
  127.     if (s.top() == 3) std::cout << "Top OK\n";
  128.     else std::cout << "Top FAIL\n";
  129.  
  130.     s.pop();
  131.     if (s.top() == 2) std::cout << "Pop OK\n";
  132.     else std::cout << "Pop FAIL\n";
  133.  
  134.     s.pop(); s.pop();
  135.     if (s.isEmpty()) std::cout << "Empty OK\n";
  136.     else std::cout << "Empty FAIL\n";
  137.  
  138.     std::cout << "\n";
  139. }
  140.  
  141. // ===== RPN Test =====
  142. void testRPN() {
  143.     std::cout << "[RPN Test]\n";
  144.  
  145.     struct TestCase {
  146.         std::string expr;
  147.         int expected;
  148.     };
  149.  
  150.     TestCase cases[] = {
  151.         {"3 4 +", 7},
  152.         {"10 2 * 3 +", 23},
  153.         {"15 7 1 1 + - / 3 * 2 1 1 + + -", 5},
  154.         {"5 1 2 + 4 * + 3 -", 14},
  155.         {"3 0 /", -888888},  // деление на 0
  156.         {"5 +", -999999},    // недостаточно операндов
  157.         {"1 2 3 +", -666666} // лишнее на стеке
  158.     };
  159.  
  160.     for (int i = 0; i < sizeof(cases) / sizeof(TestCase); ++i) {
  161.         int result = evaluateRPN(cases[i].expr);
  162.         std::cout << "Test " << i + 1 << ": ";
  163.         if (result == cases[i].expected)
  164.             std::cout << "OK";
  165.         else
  166.             std::cout << "FAIL (got " << result << ", expected " << cases[i].expected << ")";
  167.         std::cout << "\n";
  168.     }
  169.  
  170.     std::cout << "\n";
  171. }
  172.  
  173. // ===== Main =====
  174. int main() {
  175.     testStack();
  176.     testRPN();
  177.  
  178.     std::string input;
  179.     std::cout << "Enter RPN expression (e.g. '3 4 + 2 *'): ";
  180.     std::getline(std::cin, input);
  181.  
  182.     int result = evaluateRPN(input);
  183.     std::cout << "Result: " << result << "\n";
  184.  
  185.     return 0;
  186. }
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement