mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-10 05:57:14 +08:00
fix: remove potential segv from postfix_evaluation.cpp (#2995)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Evaluation of [Postfix Expression](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
|
||||
* @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).
|
||||
@@ -11,9 +12,10 @@
|
||||
* 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 <array> // for array
|
||||
#include <cassert> // for assert
|
||||
#include <iostream> // for io operations
|
||||
#include <stack> // for std::stack
|
||||
#include <string> // for stof
|
||||
|
||||
/**
|
||||
@@ -26,36 +28,6 @@ namespace others {
|
||||
* @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
|
||||
@@ -74,28 +46,29 @@ bool is_number(const std::string &s) {
|
||||
* @param stack containing numbers
|
||||
* @returns none
|
||||
*/
|
||||
void evaluate(float a, float b, const std::string &operation, Stack *stack) {
|
||||
void evaluate(float a, float b, const std::string &operation,
|
||||
std::stack<float> &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);
|
||||
c = a + b; // Addition of numbers
|
||||
stack.push(c);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
c = a - b; // Subtraction of numbers
|
||||
others::postfix_expression::push(c, stack);
|
||||
c = a - b; // Subtraction of numbers
|
||||
stack.push(c);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
c = a * b; // Multiplication of numbers
|
||||
others::postfix_expression::push(c, stack);
|
||||
c = a * b; // Multiplication of numbers
|
||||
stack.push(c);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
c = a / b; // Division of numbers
|
||||
others::postfix_expression::push(c, stack);
|
||||
c = a / b; // Division of numbers
|
||||
stack.push(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -113,31 +86,32 @@ void evaluate(float a, float b, const std::string &operation, Stack *stack) {
|
||||
*/
|
||||
template <std::size_t N>
|
||||
float postfix_evaluation(std::array<std::string, N> input) {
|
||||
Stack stack;
|
||||
std::stack<float> stack;
|
||||
int j = 0;
|
||||
|
||||
while (j < N) {
|
||||
std::string scan = input[j];
|
||||
if (is_number(scan)) {
|
||||
push(std::stof(scan), &stack);
|
||||
stack.push(std::stof(scan));
|
||||
|
||||
} else {
|
||||
float op2 = pop(&stack);
|
||||
float op1 = pop(&stack);
|
||||
const float op2 = stack.top();
|
||||
stack.pop();
|
||||
const float op1 = stack.top();
|
||||
stack.pop();
|
||||
|
||||
evaluate(op1, op2, scan, &stack);
|
||||
evaluate(op1, op2, scan, stack);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
std::cout << stack.stack[stack.stackTop] << "\n";
|
||||
std::cout << stack.top() << "\n";
|
||||
|
||||
return stack.stack[stack.stackTop];
|
||||
return stack.top();
|
||||
}
|
||||
} // namespace postfix_expression
|
||||
} // namespace others
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test function 1 with input array
|
||||
* {'2', '3', '1', '*', '+', '9', '-'}
|
||||
@@ -153,7 +127,7 @@ static void test_function_1() {
|
||||
|
||||
/**
|
||||
* @brief Test function 2 with input array
|
||||
* {'1', '2', '+', '2', '/', '5', '*', '7', '+'}
|
||||
* {'100', '200', '+', '2', '/', '5', '*', '7', '+'}
|
||||
* @returns none
|
||||
*/
|
||||
static void test_function_2() {
|
||||
@@ -164,6 +138,17 @@ static void test_function_2() {
|
||||
assert(answer == 757);
|
||||
}
|
||||
|
||||
static void test_function_3() {
|
||||
std::array<std::string, 43> input = {
|
||||
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
|
||||
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
|
||||
"+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+",
|
||||
"+", "+", "+", "+", "+", "+", "+", "+", "+", "+"};
|
||||
float answer = others::postfix_expression::postfix_evaluation(input);
|
||||
|
||||
assert(answer == 22);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
@@ -171,6 +156,7 @@ static void test_function_2() {
|
||||
int main() {
|
||||
test_function_1();
|
||||
test_function_2();
|
||||
test_function_3();
|
||||
|
||||
std::cout << "\nTest implementations passed!\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user