mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
feat: Added Postfix Evaluation (#1083)
* feat:Added Postfix evaluation * updating DIRECTORY.md * Fixed global variable name and stack def * Fixed c from int to float * Fixed clang-tidy * Modified code for larger values * Added string header * Suggested changes * Fixed clang-tidy * Apply suggestions from code review Co-authored-by: David Leal <halfpacho@gmail.com> * Added description for class * Fixed function calling * Apply suggestions from code review Co-authored-by: David Leal <halfpacho@gmail.com> * Updated evaluate function documentation * Apply suggestions from code review Co-authored-by: David Leal <halfpacho@gmail.com> * Update others/postfix_evaluation.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update others/postfix_evaluation.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: Darshana-Sarma <lownish@hotmail.com> Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>
This commit is contained in:
parent
b09b3da69a
commit
bcf79e259a
@ -190,6 +190,7 @@
|
|||||||
* [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/palindrome_of_number.cpp)
|
* [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/palindrome_of_number.cpp)
|
||||||
* [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/paranthesis_matching.cpp)
|
* [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/paranthesis_matching.cpp)
|
||||||
* [Pascal Triangle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/pascal_triangle.cpp)
|
* [Pascal Triangle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/pascal_triangle.cpp)
|
||||||
|
* [Postfix Evaluation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/postfix_evaluation.cpp)
|
||||||
* [Primality Test](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/primality_test.cpp)
|
* [Primality Test](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/primality_test.cpp)
|
||||||
* [Smallest Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest_circle.cpp)
|
* [Smallest Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest_circle.cpp)
|
||||||
* [Sparse Matrix](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sparse_matrix.cpp)
|
* [Sparse Matrix](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sparse_matrix.cpp)
|
||||||
|
178
others/postfix_evaluation.cpp
Normal file
178
others/postfix_evaluation.cpp
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Evaluation of [Postfix Expression](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
|
||||||
|
* @author [Darshana Sarma](https://github.com/Darshana-Sarma)
|
||||||
|
* @details
|
||||||
|
* Create a stack to store operands (or values).
|
||||||
|
* Scan the given expression and do following for every scanned element.
|
||||||
|
* If the element is a number, push it into the stack
|
||||||
|
* If the element is a operator, pop operands for the operator from stack.
|
||||||
|
* Evaluate the operator and push the result back to the stack
|
||||||
|
* When the expression is ended, the number in the stack is the final answer
|
||||||
|
*/
|
||||||
|
#include <algorithm> // for all_of
|
||||||
|
#include <array> // for std::array
|
||||||
|
#include <cassert> // for assert
|
||||||
|
#include <iostream> // for io operations
|
||||||
|
#include <string> // for stof
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace others
|
||||||
|
* @brief Other algorithms
|
||||||
|
*/
|
||||||
|
namespace others {
|
||||||
|
/**
|
||||||
|
* @namespace postfix_expression
|
||||||
|
* @brief Functions for Postfix Expression algorithm
|
||||||
|
*/
|
||||||
|
namespace postfix_expression {
|
||||||
|
/**
|
||||||
|
* @brief Creates an array to be used as stack for storing values
|
||||||
|
*/
|
||||||
|
class Stack {
|
||||||
|
public:
|
||||||
|
std::array<float, 20> stack{}; ///< Array which will be used to store numbers in the input
|
||||||
|
int stackTop = -1; ///< Represents the index of the last value added to array. -1 means array is empty
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushing operand, also called the number in the array to the stack
|
||||||
|
* @param operand float value from the input array or evaluation
|
||||||
|
* @param stack stack containing numbers
|
||||||
|
* @returns none
|
||||||
|
*/
|
||||||
|
void push(float operand, Stack *stack) {
|
||||||
|
stack->stackTop++;
|
||||||
|
stack->stack[stack->stackTop] = operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Popping operand, also called the number from the stack
|
||||||
|
* @param stack stack containing numbers
|
||||||
|
* @returns operand float on top of stack
|
||||||
|
*/
|
||||||
|
float pop(Stack *stack) {
|
||||||
|
float operand = stack->stack[stack->stackTop];
|
||||||
|
stack->stackTop--;
|
||||||
|
return operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if scanned string is a number
|
||||||
|
* @param s scanned string
|
||||||
|
* @returns bool boolean value if string is number
|
||||||
|
*/
|
||||||
|
bool is_number(const std::string &s) {
|
||||||
|
return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Evaluate answer using given last two operands from and operation
|
||||||
|
* @param a second last added operand which will be used for evaluation
|
||||||
|
* @param b last added operand which will be used for evaluation
|
||||||
|
* @param operation to be performed with respective floats
|
||||||
|
* @param stack containing numbers
|
||||||
|
* @returns none
|
||||||
|
*/
|
||||||
|
void evaluate(float a, float b, const std::string &operation, Stack *stack) {
|
||||||
|
float c = 0;
|
||||||
|
const char *op = operation.c_str();
|
||||||
|
switch (*op) {
|
||||||
|
case '+':
|
||||||
|
c = a + b; // Addition of numbers
|
||||||
|
others::postfix_expression::push(c, stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
c = a - b; // Subtraction of numbers
|
||||||
|
others::postfix_expression::push(c, stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
c = a * b; // Multiplication of numbers
|
||||||
|
others::postfix_expression::push(c, stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
c = a / b; // Division of numbers
|
||||||
|
others::postfix_expression::push(c, stack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::cout << "Operator not defined\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Postfix Evaluation algorithm to compute the value from given input
|
||||||
|
* array
|
||||||
|
* @tparam N number of array size
|
||||||
|
* @param input Array of characters consisting of numbers and operations
|
||||||
|
* @returns stack[stackTop] returns the top value from the stack
|
||||||
|
*/
|
||||||
|
template <std::size_t N>
|
||||||
|
float postfix_evaluation(std::array<std::string, N> input) {
|
||||||
|
Stack stack;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while (j < N) {
|
||||||
|
std::string scan = input[j];
|
||||||
|
if (is_number(scan)) {
|
||||||
|
push(std::stof(scan), &stack);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float op2 = pop(&stack);
|
||||||
|
float op1 = pop(&stack);
|
||||||
|
|
||||||
|
evaluate(op1, op2, scan, &stack);
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << stack.stack[stack.stackTop] << "\n";
|
||||||
|
|
||||||
|
return stack.stack[stack.stackTop];
|
||||||
|
}
|
||||||
|
} // namespace postfix_expression
|
||||||
|
} // namespace others
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test function 1 with input array
|
||||||
|
* {'2', '3', '1', '*', '+', '9', '-'}
|
||||||
|
* @returns none
|
||||||
|
*/
|
||||||
|
static void test_function_1() {
|
||||||
|
std::array<std::string, 7> input = {"2", "3", "1", "*", "+", "9", "-"};
|
||||||
|
|
||||||
|
float answer = others::postfix_expression::postfix_evaluation(input);
|
||||||
|
|
||||||
|
assert(answer == -4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test function 2 with input array
|
||||||
|
* {'1', '2', '+', '2', '/', '5', '*', '7', '+'}
|
||||||
|
* @returns none
|
||||||
|
*/
|
||||||
|
static void test_function_2() {
|
||||||
|
std::array<std::string, 9> input = {"100", "200", "+", "2", "/",
|
||||||
|
"5", "*", "7", "+"};
|
||||||
|
float answer = others::postfix_expression::postfix_evaluation(input);
|
||||||
|
|
||||||
|
assert(answer == 757);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main function
|
||||||
|
* @returns 0 on exit
|
||||||
|
*/
|
||||||
|
int main() {
|
||||||
|
test_function_1();
|
||||||
|
test_function_2();
|
||||||
|
|
||||||
|
std::cout << "\nTest implementations passed!\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user