CPP09 1.0
読み取り中…
検索中…
一致する文字列を見つけられません
RPN.cpp
[詳解]
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* RPN.cpp :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: kamitsui <kamitsui@student.42tokyo.jp> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2025/08/28 19:12:50 by kamitsui #+# #+# */
9/* Updated: 2025/08/28 19:13:23 by kamitsui ### ########.fr */
10/* */
11/* ************************************************************************** */
12
17#include "RPN.hpp"
18
19// --- Orthodox Canonical Form ---
20
22
24
25// コピーコンストラクタ(実装は不要)
26RPN::RPN(const RPN &src) { (void)src; }
27
28// 代入演算子(実装は不要)
29RPN &RPN::operator=(const RPN &rhs) {
30 (void)rhs;
31 return *this;
32}
33
34// --- Private Helper Methods Implementation ---
35
36// トークンが有効な演算子かチェック
37bool RPN::isOperator(const std::string &token) const {
38 return token.length() == 1 && (token[0] == '+' || token[0] == '-' || token[0] == '*' || token[0] == '/');
39}
40
41// 演算を実行
42void RPN::performOperation(char op) {
43 // スタックに2つ以上のオペランド(被演算子)があるか確認
44 if (_stack.size() < 2) {
45 throw std::runtime_error("Error: Not enough operands for operation.");
46 }
47
48 // スタックから2つのオペランドを取り出す
49 // 最初に取り出すのが右オペランド(rhs)、次が左オペランド(lhs)
50 int rhs = _stack.top();
51 _stack.pop();
52 int lhs = _stack.top();
53 _stack.pop();
54
55 int result = 0;
56 switch (op) {
57 case '+':
58 result = lhs + rhs;
59 break;
60 case '-':
61 result = lhs - rhs;
62 break;
63 case '*':
64 result = lhs * rhs;
65 break;
66 case '/':
67 if (rhs == 0) {
68 throw std::runtime_error("Error: Division by zero.");
69 }
70 result = lhs / rhs;
71 break;
72 }
73 // 計算結果をスタックに戻す
74 _stack.push(result);
75}
76
77// --- Public Methods Implementation ---
78
79// RPN数式を評価する
80void RPN::evaluate(const std::string &expression) {
81 std::stringstream ss(expression);
82 std::string token;
83
84 // 文字列をスペースで区切ってトークンごとに処理
85 while (ss >> token) {
86 // トークンが数字の場合
87 if (token.length() == 1 && isdigit(token[0])) {
88 _stack.push(token[0] - '0'); // 文字を整数に変換してスタックにプッシュ
89 }
90 // トークンが演算子の場合
91 else if (isOperator(token)) {
92 performOperation(token[0]);
93 }
94 // それ以外の無効なトークンの場合
95 else {
96 throw std::runtime_error("Error: Invalid token found in expression.");
97 }
98 }
99
100 // 全てのトークン処理後、スタックに結果が1つだけ残っているか確認
101 if (_stack.size() != 1) {
102 throw std::runtime_error("Error: Invalid expression format.");
103 }
104
105 // 最終結果を出力
106 std::cout << _stack.top() << std::endl;
107}
逆ポーランド記法(RPN)の数式を評価するRPNクラスを提供します。
逆ポーランド記法の数式を評価するためのクラス。
Definition RPN.hpp:35
RPN()
デフォルトコンストラクタ。
Definition RPN.cpp:21
void evaluate(const std::string &expression)
逆ポーランド記法の数式文字列を評価します。
Definition RPN.cpp:80
~RPN()
デストラクタ。
Definition RPN.cpp:23
T endl(T... args)
T pop(T... args)
T push(T... args)
T length(T... args)
T top(T... args)