C++で前置記法(プレフィックス)から後置記法(ポストフィックス)へ変換する方法
この問題では、前置記法(プレフィックス)で表された式が与えられ、それを後置記法(ポストフィックス)に変換して出力することが求められます。
前置記法と後置記法とは
前置記法(プレフィックス記法)は、演算子がオペランド(被演算子)の前に置かれる表記方法です。
例:+AB
後置記法(ポストフィックス記法)は、演算子がオペランドの後に置かれる表記方法です。
例:AB+
なお、この変換処理では、中置記法(インフィックス)を経由せずに、直接前置記法から後置記法へ変換する必要があります。
問題例
具体的な例を見てみましょう。
入力:/+XY+NM 出力:XY+NM+/ 説明:中置記法に直すと (X+Y)/(N+M)
解決アプローチ
この問題を解くには、まず前置記法の式全体を逆順(右から左)に走査します。そして、処理にはスタックというデータ構造を使用します。走査中に見つかった要素ごとに、以下のように処理を行います。
- オペランドの場合:スタックに要素をプッシュ(push)します。
- 演算子の場合:スタックから要素を2回ポップ(pop)し、「オペランド1 + オペランド2 + 演算子」の順序で連結した文字列を作成して、再びスタックにプッシュします。
すべての走査が完了した時点で、スタックの最上位にある文字列が求める後置記法の式となります。
C++での実装例
上記のアルゴリズムを実装したプログラムが以下の通りです。
#include <iostream>
#include <stack>
using namespace std;
bool isOperator(char x) {
switch (x) {
case '+':
case '-':
case '/':
case '*':
return true;
}
return false;
}
string convertToPostfix(string prefix) {
stack<string> expression;
int length = prefix.size();
for (int i = length - 1; i >= 0; i--) {
if (isOperator(prefix[i])) {
string op1 = expression.top();
expression.pop();
string op2 = expression.top();
expression.pop();
string temp = op1 + op2 + prefix[i];
expression.push(temp);
}
else
expression.push(string(1, prefix[i]));
}
return expression.top();
}
int main() {
string prefix = "*-AB/+CD*XY";
cout << "Prefix expression : " << prefix << endl;
cout << "Postfix expression : " << convertToPostfix(prefix);
return 0;
}
実行結果
Prefix expression : *-AB/+CD*XY Postfix expression : AB-CD+XY*/*
まとめ
このように、式を逆順に走査しながらスタックを操作することで、中置記法を経由することなく、前置記法から後置記法へ効率的に変換できます。時間計算量はO(n)、空間計算量もO(n)であり、非常にシンプルかつ実用的なアルゴリズムです。
-
C++で式ツリー(Expression Tree)を評価する方法|再帰を使った実装例
本記事では、+、-、*、/ といった二項演算子から構成される式ツリー(Expression Tree)を評価し、その計算結果を返す問題について解説します。 式ツリーとは 式ツリーは二分木の一種であり、各ノードには演算子またはオペランド(被演算数)が格納されます。ノードの役割は次のように分けられます。 葉ノード:演算の対象となる値(オペランド)を保持します。 非葉ノード(内部ノード):実行すべき演算を表す二項演算子を保持します。 式ツリーを中順走査(in-order traversal)すると、元の中置記法の数式が復元できるのが特徴です。 例題で理解しよう 入力:次のような式ツリーが与えられ
-
C++で二分木を二分探索木(BST)へ変換する方法を解説
二分木(Binary Tree)とは二分木とは、木構造の各ノードが最大で2つの子ノードを持つことができる特別な木構造です。これらの子ノードは、それぞれ「左の子ノード」と「右の子ノード」と呼ばれます。シンプルな二分木の例は以下の通りです。二分探索木(BST)とは二分探索木(BST)は、以下のルールに従う特別な木構造です。左の子ノードの値は、常に親ノードの値より小さい右の子ノードの値は、常に親ノードの値より大きいすべてのノードが、それぞれ独立して二分探索木の性質を満たす二分探索木(BST)の例は以下の通りです。二分探索木は、検索や最小値・最大値の探索といった操作の計算量を削減するために用いられるデ