Skip to content

Commit

Permalink
Директно пресмятане на израз в обратен полски запис
Browse files Browse the repository at this point in the history
  • Loading branch information
triffon committed Oct 20, 2022
1 parent 5f094a1 commit db2c066
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lectures/1/calculator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(calculator VERSION 0.1.0)
include(CTest)
enable_testing()

add_executable(calculator main.cpp rpn_calculator.cpp calculator.cpp)
add_executable(calculator main.cpp rpn_calculator.cpp calculator.cpp rpn_direct_calculator.cpp)
include_directories(../common ../stack)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
Expand Down
13 changes: 9 additions & 4 deletions lectures/1/calculator/calculator_tests.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <strstream>
#include "doctest.h"
#include "rpn_calculator.hpp"
#include "rpn_direct_calculator.hpp"
#include "rpn_converter.hpp"

TEST_CASE("Тестовият израз в обратен полски запис се пресмята коректно") {
RPNCalculator c;
Expand Down Expand Up @@ -43,12 +46,14 @@ TEST_CASE("Тестов израз в инфиксен запис се прео
CHECK_EQ(c.toRPN("(1+2)*(3-4/5)"), "12+345/-*");
}

TEST_CASE("Тестов израз в инфиксен запис се пресмята коректно") {
RPNCalculator c;
TEST_CASE_TEMPLATE("Тестов израз в инфиксен запис се пресмята коректно",
SomeCalculator, RPNCalculator, RPNDirectCalculator) {
SomeCalculator c;
CHECK_EQ(c.calculate("(1+2)*(3-4/5)"), doctest::Approx(6.6));
}

TEST_CASE("Друг тестов израз в инфиксен запис се пресмята коректно") {
RPNCalculator c;
TEST_CASE_TEMPLATE("Друг тестов израз в инфиксен запис се пресмята коректно",
SomeCalculator, RPNCalculator, RPNDirectCalculator) {
SomeCalculator c;
CHECK_EQ(c.calculate("(1+2)*(3/4-5)"), doctest::Approx(-12.75));
}
35 changes: 35 additions & 0 deletions lectures/1/calculator/rpn_direct_calculator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "rpn_direct_calculator.hpp"

void RPNDirectCalculator::processOperation(char op) {
double rightop = resultStack.pop();
double leftop = resultStack.pop();
resultStack.push(applyOperation(leftop, op, rightop));
}

double RPNDirectCalculator::calculate(std::string const& expr) {
for(char c : expr) {
if (isdigit(c))
resultStack.push(digitToValue(c));
else if (isop(c) || c == '(') {
char op;
while (!operationStack.empty() &&
operationStack.peek() != '(' &&
priority(operationStack.peek()) >= priority(c))
processOperation(operationStack.pop());
operationStack.push(c);
}
else if (c == ')') {
char op;
while ((op = operationStack.pop()) != '(')
processOperation(op);
} else
throw std::runtime_error("Некоректен израз: непознат символ!");
}
while (!operationStack.empty())
processOperation(operationStack.pop());

double result = resultStack.pop();
if (!resultStack.empty())
throw std::runtime_error("Некоректен израз: повече цифри от операции!");
return result;
}
18 changes: 18 additions & 0 deletions lectures/1/calculator/rpn_direct_calculator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef __RPN_DIRECT_CALCULATOR_HPP
#define __RPN_DIRECT_CALCULATOR_HPP

#include "lstack.hpp"
#include "calculator.hpp"

class RPNDirectCalculator : public Calculator {
private:
LinkedStack<double> resultStack;
LinkedStack<char> operationStack;

void processOperation(char op);

public:
double calculate(std::string const& s);
};

#endif

0 comments on commit db2c066

Please sign in to comment.