This commit is contained in:
louiscklaw
2025-01-31 21:27:38 +08:00
parent 8cce226ca9
commit ca0eb416dd
90 changed files with 4082 additions and 0 deletions

BIN
marissa.sam/task2/temp/1721723283615.jpg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,123 @@
#include <iostream>
#include <stack>
#include <cctype>
#include <cstring>
// 1. how to read and store the input?
std::string readInput()
{
std::string input;
char c;
while (std::cin.get(c)) {
if (c == '\n')
break;
input += c;
}
return input;
}
// 2. pseudo code of the algorithm
// convert to postfix expression use stack,
// 1. if it is an operand, push it into stack,
// 2. if it is an operator, pop the top two elements and push the operator result,
// 3. if it is a bracket, pop until the matched bracket, then push it into stack,
// 4. if the input is end, pop all the remaining elements,
// 5. if the last element is a bracket, return error,
// else return the result
std::string infixToPostfix(const std::string& input)
{
std::stack<char> stack;
std::string postfix;
const char* precedence = "+-*/()";
for (const auto& c : input) {
if (std::isalpha(c) || std::isdigit(c)) {
postfix += c;
} else if (c == '(') {
stack.push(c);
} else if (c == ')') {
while (!stack.empty() && stack.top() != '(') {
postfix += stack.top();
stack.pop();
}
if (!stack.empty()) {
stack.pop();
}
} else {
while (!stack.empty() && precedence[c] <= precedence[stack.top()]) {
postfix += stack.top();
stack.pop();
}
stack.push(c);
}
}
while (!stack.empty()) {
postfix += stack.top();
stack.pop();
}
return postfix;
}
// 3. data structures used in the algorithm
// stack
// string
// 4. time complexity
// O(n), where n is the length of input
// 5. space complexity
// O(n), where n is the length of input
// 6. how to store the postfix expression?
// using string
int main()
{
std::string input = readInput();
std::string postfix = infixToPostfix(input);
std::cout << postfix << std::endl;
// 1. how to read the postfix expression
// read postfix expression from standard input stream and store them into string
// 2. pseudo code of the algorithm
// evaluate a postfix expression use stack,
// if it is an operand, push it into stack,
// if it is an operator, pop the top two elements, apply the operator, and push the result,
// if it is a bracket, pop until the matched bracket, then push it into stack,
// if the input is end, return the last element in stack,
// else error
std::stack<int> stack;
const char* operators = "+-*/";
for (const auto& c : postfix) {
if (std::isalpha(c) || std::isdigit(c)) {
stack.push(c - '0');
} else if (std::strchr(operators, c)) {
int operand2 = stack.top();
stack.pop();
int operand1 = stack.top();
stack.pop();
switch (c) {
case '+':
stack.push(operand1 + operand2);
break;
case '-':
stack.push(operand1 - operand2);
break;
case '*':
stack.push(operand1 * operand2);
break;
case '/':
stack.push(operand1 / operand2);
break;
default:
return -1;
}
} else {
return -1;
}
}
std::cout << stack.top() << std::endl;
return 0;
}

View File

@@ -0,0 +1,121 @@
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
#include <map>
// Function to convert infix expression to postfix expression
std::string infixToPostfix(const std::string &infix)
{
std::stack<char> s;
std::string postfix;
std::map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'(', 0}};
for (char c : infix)
{
if (std::isalnum(c))
{ // 1. if operand, add to postfix
postfix += c;
}
else if (c == '(')
{ // 2. if '(', push to stack
s.push(c);
}
else if (c == ')')
{ // 3. if ')', pop until '('
while (!s.empty() && s.top() != '(')
{
postfix += s.top();
s.pop();
}
if (!s.empty())
s.pop(); // pop '('
}
else
{ // 4. if operator, pop operators with greater or equal precedence
while (!s.empty() && precedence[c] <= precedence[s.top()])
{
postfix += s.top();
s.pop();
}
s.push(c); // push current operator
}
}
// 5. pop remaining operators
while (!s.empty())
{
postfix += s.top();
s.pop();
}
return postfix;
}
// Function to evaluate postfix expression
int evaluatePostfix(const std::string &postfix)
{
std::stack<int> s;
for (char c : postfix)
{
if (std::isdigit(c))
{ // 1. if operand, push to stack
s.push(c - '0');
}
else
{ // 2. if operator, pop two operands, evaluate and push result
int op2 = s.top();
s.pop();
int op1 = s.top();
s.pop();
switch (c)
{
case '+':
s.push(op1 + op2);
break;
case '-':
s.push(op1 - op2);
break;
case '*':
s.push(op1 * op2);
break;
case '/':
s.push(op1 / op2);
break;
}
}
}
return s.top(); // 3. result is the only element in stack
}
int main()
{
std::string infix;
// std::cout << "Enter an arithmetic expression: ";
// std::getline(std::cin, infix);
std::cout << "e.g. 1 1+4*5" << std::endl;
infix = "1+4*5";
std::string postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
int result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
std::cout << "e.g. 2 (1+4)*5" << std::endl;
infix = "(1+4)*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
std::cout << "e.g. 3 1+4-5" << std::endl;
infix = "1+4-5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
return 0;
}

View File

@@ -0,0 +1,103 @@
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
#include <map>
// Function to convert infix expression to postfix expression
std::string infixToPostfix(const std::string &infix)
{
std::stack<char> s;
std::string postfix;
std::map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'(', 0}};
for (char c : infix)
{
if (std::isalnum(c))
{ // 1. if operand, add to postfix
postfix += c;
}
else if (c == '(')
{ // 2. if '(', push to stack
s.push(c);
}
else if (c == ')')
{ // 3. if ')', pop until '('
while (!s.empty() && s.top() != '(')
{
postfix += s.top();
s.pop();
}
if (!s.empty())
s.pop(); // pop '('
}
else
{ // 4. if operator, pop operators with greater or equal precedence
while (!s.empty() && precedence[c] <= precedence[s.top()])
{
postfix += s.top();
s.pop();
}
s.push(c); // push current operator
}
}
// 5. pop remaining operators
while (!s.empty())
{
postfix += s.top();
s.pop();
}
return postfix;
}
// Function to evaluate postfix expression
int evaluatePostfix(const std::string &postfix)
{
std::stack<int> s;
for (char c : postfix)
{
if (std::isdigit(c))
{ // 1. if operand, push to stack
s.push(c - '0');
}
else
{ // 2. if operator, pop two operands, evaluate and push result
int op2 = s.top();
s.pop();
int op1 = s.top();
s.pop();
switch (c)
{
case '+':
s.push(op1 + op2);
break;
case '-':
s.push(op1 - op2);
break;
case '*':
s.push(op1 * op2);
break;
case '/':
s.push(op1 / op2);
break;
}
}
}
return s.top(); // 3. result is the only element in stack
}
int main()
{
std::string infix;
std::cout << "Enter an arithmetic expression: ";
std::getline(std::cin, infix);
std::string postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
int result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
return 0;
}

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -ex
g++ -o output helloworld.cpp
echo "build done"
./output

BIN
marissa.sam/task2/temp/chrome_OQtOQkTD0a.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,185 @@
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
#include <map>
// 2. pseudo code of the algorithm
// convert to postfix expression use stack,
// 1. if it is an operand, add to postfix,
// 2. if it is an operator,
// 2.1 if it is the first operator, push into `s` stack
// 2.2 if `s` stack already got element, compare the weight of opreators
// 2.3 pop `s` stack until the top most one got smaller precedence
// 3. if it is a bracket, push into stack `s`,
// 3. if it is a closing bracket, pop all element from `s` stack back to postfix,
// else return the result
// Function to convert infix expression to postfix expression
std::string infixToPostfix(const std::string &infix)
{
std::stack<char> s;
std::string postfix;
std::map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'(', 0}};
for (char c : infix)
{
if (std::isalnum(c))
{ // 1. if operand, add to postfix
postfix += c;
}
// 其實括號入面同括號出面嘅數你當佢兩條式計就得
else if (c == '(')
{ // 2. if '(', push to stack
s.push(c);
}
// 咁去呢度關括號呀嘛,
// 咁佢咪會由個 stack 嗰度 port 返曬啲operator出嚟囉, 變咗可以 14+5*
else if (c == ')')
{ // 3. if ')', pop until '('
while (!s.empty() && s.top() != '(')
{
postfix += s.top();
s.pop();
}
if (!s.empty())
s.pop(); // pop '('
}
else
{ // 4. if operator, pop operators with greater or equal precedence
while (!s.empty() && precedence[c] <= precedence[s.top()])
{
postfix += s.top();
s.pop();
}
s.push(c); // push current operator
}
}
// 5. pop remaining operators, LIFO
while (!s.empty())
{
postfix += s.top();
s.pop();
}
return postfix;
}
// Function to evaluate postfix expression
// 2. pseudo code of the algorithm
// evaluate a postfix expression use stack,
// if it is an operand, push it into stack,
// if it is an operator, pop the top two elements, apply the operator, and push the result,
// if it is a bracket, pop until the matched bracket, then push it into stack,
// if the input is end, return the last element in stack,
// else error
int evaluatePostfix(const std::string &postfix)
{
std::stack<int> s;
for (char c : postfix)
{
if (std::isdigit(c))
{ // 1. if operand, push to stack
s.push(c - '0');
}
else
{ // 2. if operator, pop two operands, evaluate and push result
int op2 = s.top();
s.pop();
int op1 = s.top();
s.pop();
switch (c)
{
case '+':
s.push(op1 + op2);
break;
case '-':
s.push(op1 - op2);
break;
case '*':
s.push(op1 * op2);
break;
case '/':
s.push(op1 / op2);
break;
}
}
}
return s.top(); // 3. result is the only element in stack
}
int main()
{
std::string infix;
// std::cout << "Enter an arithmetic expression: ";
// std::getline(std::cin, infix);
// --- part 2 iteration:
// 1,4,5,*,+
// 1,20,+
// 21
std::cout << "e.g. 1 1+4*5" << std::endl;
infix = "1+4*5";
std::string postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
int result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,+,5,*
// 5,5,*
// 25
std::cout << "e.g. 2 (1+4)*5" << std::endl;
infix = "(1+4)*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,+,5,-
// 5,5,-
// 0
std::cout << "e.g. 3 1+4-5" << std::endl;
infix = "1+4-5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,5,*,+,5,*
// 1,20,+,5,*
// 21,5,*
// 105
std::cout << "e.g. 4 (1+4*5)*5" << std::endl;
infix = "(1+4*5)*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,5,*,+,2,5,*,-
// =>1,20,+,2,5,*,-
// =>21,2,5,*,-
// =>21,10,-
// =>11
std::cout << "e.g. 5 (1+4*5)-2*5" << std::endl;
infix = "(1+4*5)-2*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
return 0;
}

View File

@@ -0,0 +1,185 @@
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
#include <map>
// 2. pseudo code of the algorithm
// convert to postfix expression use stack,
// 1. if it is an operand, add to postfix,
// 2. if it is an operator,
// 2.1 if it is the first operator, push into `s` stack
// 2.2 if `s` stack already got element, compare the weight of opreators
// 2.3 pop `s` stack until the top most one got smaller precedence
// 3. if it is a bracket, push into stack `s`,
// 3. if it is a closing bracket, pop all element from `s` stack back to postfix,
// else return the result
// Function to convert infix expression to postfix expression
std::string infixToPostfix(const std::string &infix)
{
std::stack<char> s;
std::string postfix;
std::map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'(', 0}};
for (char c : infix)
{
if (std::isalnum(c))
{ // 1. if operand, add to postfix
postfix += c;
}
// 其實括號入面同括號出面嘅數你當佢兩條式計就得
else if (c == '(')
{ // 2. if '(', push to stack
s.push(c);
}
// 咁佢呢度關括號呀嘛,
// 咁佢咪會由個 stack 嗰度 port 返曬啲operator出嚟囉, 變咗可以 14+5*
else if (c == ')')
{ // 3. if ')', pop until '('
while (!s.empty() && s.top() != '(')
{
postfix += s.top();
s.pop();
}
if (!s.empty())
s.pop(); // pop '('
}
else
{ // 4. if operator, pop operators with greater or equal precedence
while (!s.empty() && precedence[c] <= precedence[s.top()])
{
postfix += s.top();
s.pop();
}
s.push(c); // push current operator
}
}
// 5. pop remaining operators, LIFO
while (!s.empty())
{
postfix += s.top();
s.pop();
}
return postfix;
}
// Function to evaluate postfix expression
// 2. pseudo code of the algorithm
// evaluate a postfix expression use stack,
// if it is an operand, push it into stack,
// if it is an operator, pop the top two elements, apply the operator, and push the result,
// if it is a bracket, pop until the matched bracket, then push it into stack,
// if the input is end, return the last element in stack,
// else error
int evaluatePostfix(const std::string &postfix)
{
std::stack<int> s;
for (char c : postfix)
{
if (std::isdigit(c))
{ // 1. if operand, push to stack
s.push(c - '0');
}
else
{ // 2. if operator, pop two operands, evaluate and push result
int op2 = s.top();
s.pop();
int op1 = s.top();
s.pop();
switch (c)
{
case '+':
s.push(op1 + op2);
break;
case '-':
s.push(op1 - op2);
break;
case '*':
s.push(op1 * op2);
break;
case '/':
s.push(op1 / op2);
break;
}
}
}
return s.top(); // 3. result is the only element in stack
}
int main()
{
std::string infix;
// std::cout << "Enter an arithmetic expression: ";
// std::getline(std::cin, infix);
// --- part 2 iteration:
// 1,4,5,*,+
// 1,20,+
// 21
std::cout << "e.g. 1 1+4*5" << std::endl;
infix = "1+4*5";
std::string postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
int result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,+,5,*
// 5,5,*
// 25
std::cout << "e.g. 2 (1+4)*5" << std::endl;
infix = "(1+4)*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,+,5,-
// 5,5,-
// 0
std::cout << "e.g. 3 1+4-5" << std::endl;
infix = "1+4-5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,5,*,+,5,*
// 1,20,+,5,*
// 21,5,*
// 105
std::cout << "e.g. 4 (1+4*5)*5" << std::endl;
infix = "(1+4*5)*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
// --- part 2 iteration:
// 1,4,5,*,+,2,5,*,-
// =>1,20,+,2,5,*,-
// =>21,2,5,*,-
// =>21,10,-
// =>11
std::cout << "e.g. 5 (1+4*5)-2*5" << std::endl;
infix = "(1+4*5)-2*5";
postfix = infixToPostfix(infix);
std::cout << "Postfix expression: " << postfix << std::endl;
result = evaluatePostfix(postfix);
std::cout << "Result: " << result << std::endl;
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,31 @@
# Task
I want you to write a simple calculator to evaluate arithmetic expressions.
Solve your problem step by step with C++.
Please consider the precedence of operators as well.
## It includes two parts:
- In the first part, you need to convert the input to a postfix expression.
- In the second part, you need to evaluate the postfix expression that you get in the first
part.
- You need to implement your algorithms using c++.
- You also need to write comment inside the code explaining the following items.
## Part 1: Convert an expression to postfix expression using stack in STL
1. how to read and store the input?
2. pseudo code of the algorithm
3. data structures used in the algorithm
4. time complexity
5. space complexity
6. how to store the postfix expression?
## Part 2: Use stack of STL to evaluate a postfix expression
1. how to read the postfix expression
2. pseudo code of the algorithm
3. data structures used in the algorithm
4. time complexity
5. space complexity
6. how to output the final result?