Java プログラミング スキル - データ構造とアルゴリズム「プレフィックス、インフィックス、サフィックス」

Java プログラミング スキル - データ構造とアルゴリズム「プレフィックス、インフィックス、サフィックス」

[[387421]]

接頭辞表現(ポーランド語表記)

プレフィックス式はポーランド式とも呼ばれます。プレフィックス式の演算子は演算子の前に置かれます。たとえば、(3+4)*5-6に対応するプレフィックス式は - * + 3 4 5 6 です。

コンピュータによる前置表現の評価

式を右から左にスキャンします。数値に遭遇すると、スタックにプッシュされます。演算子に遭遇すると、スタックの一番上の 2 つの数値がポップアウトされ、演算子を使用してそれら (一番上の要素と 2 番目に上の要素) に対応する計算が実行され、結果がスタックにプッシュされます。上記のプロセスを式の左端まで繰り返し、最後の計算で得られた値が式の結果になります。

たとえば、(3+4)*5-6 に対応するプレフィックス式は - * + 3 4 5 6 です。プレフィックス式を評価する手順は次のとおりです。

  1. 右から左にスキャンし、6、5、4、3 をスタックにプッシュします。
  2. + 演算子に遭遇すると、3 と 4 がポップされ (3 はスタックの一番上の要素、4 は 2 番目に上の要素)、3+4 の値が計算され、7 が取得され、7 がスタックにプッシュされます。
  3. 次に * 演算子が来るので、7 と 5 がポップされ、35 が計算され、35 がスタックにプッシュされます。
  4. 最後に、- 演算子は 35-6 の値、つまり 29 を計算し、これが最終結果となります。

中置表現

中置式は、(3*4)+5-6 のような一般的な算術式です。中置式の評価は人間にとって最も馴染み深いものですが、コンピュータにとっては操作が難しいため、結果を計算する際には中置式を他の式に変換して演算することがよくあります (通常は後置式に変換されます)。

接尾辞表現

逆ポーランド記法とも呼ばれる後置式は、演算子がオペランドの後に来る点を除いて、前置式に似ています。

例えば、(3+4)*5-6に対応する接尾辞式は3 4 + 5 * 6 -

例えば

接尾辞表現のコンピュータ評価

式を左から右にスキャンします。数値に遭遇したら、その数値をスタックにプッシュします。演算子に遭遇したら、スタックの一番上の 2 つの要素をポップし、演算子を使用してそれら (一番上の要素と 2 番目に上の要素) に対応する計算を実行し、結果をスタックにプッシュします。右端が表されるまで、上記のプロセスを繰り返します。最後の計算によって得られた値が式の結果です。

たとえば、(3+4)*5-6 に対応するサフィックス式は 3 4 + 5 * 6 - です。サフィックス式を評価する手順は次のとおりです。

  1. 左から右にスキャンして、3 と 4 をスタックにプッシュします。
  2. + 演算子に遭遇すると、4 と 3 がポップされ (4 はスタックの一番上の要素、3 は 2 番目に上の要素)、7 が計算され、7 がスタックにプッシュされます。
  3. スタックに 5 をプッシュします。
  4. * 演算子に遭遇すると、5 と 7 が取り出され、35 が計算され、35 がスタックにプッシュされます。
  5. 6 をスタックにプッシュします。
  6. 最後に、- 演算子は 29 を計算し、最終結果を返します。

中置式を後置式に変換する

1. 空の中間結果を格納するための演算子スタック s1 とスタック s2 の 2 つのスタックを初期化します。

2. 式を左から右にスキャンします。

3. オペランドが見つかったら、それを s2 にプッシュします。

4. 演算子に遭遇すると、その優先順位を s1 の最上位の演算子と比較します。

  1. s1 が空の場合、またはスタックの一番上の演算子が左括弧 "(" の場合、演算子はスタックに直接プッシュされます。
  2. それ以外の場合、優先順位がスタックの一番上の演算子よりも高い場合は、その演算子も s1 にプッシュされます。
  3. それ以外の場合は、s1のスタックの一番上の演算子をポップしてs2にプッシュし、再び(4.1)に戻ってs1の新しい一番上の演算子と比較します。

5. 括弧に遭遇したとき:

  1. 左括弧「(」の場合は、直接 s1 にプッシュされます。
  2. 右括弧 ")" の場合、左括弧が検出されるまで、s1 のスタックの先頭にある演算子が 1 つずつポップアウトされ、s2 にプッシュされます。左括弧が検出されると、括弧のペアは破棄されます。

6. 式が右端に達するまで手順 2 ~ 5 を繰り返します。

7. s1 の残りの演算子をポップし、1 つずつ s2 にプッシュします。

8. s2 の要素を 1 つずつ取り出して出力します。結果の逆順が、中置式に対応する後置式になります。

シンプルな接尾辞式計算機

  1. パッケージ com.structures.stack;
  2.  
  3. java.util.ArrayList をインポートします。
  4. java.util.Arrays をインポートします。
  5. java.util.List をインポートします。
  6. java.util.Stack をインポートします。
  7.  
  8. パブリッククラス PolandNotation {
  9. 公共 静的void main(String[] args) {
  10. //まず逆ポーランド語表現を与えます (3+4)*5-6==>3 4 + 5 * 6 -
  11. 文字列式 = "1+(((2+3)*4))-5" ;
  12. リスト<文字列> toInfixExpressionList = toInfixExpressionList(式);
  13. System.out.println (toInfixExpressionList) ;
  14. リスト<文字列> suffixExpressList = parseSuffixExpressList(toInfixExpressionList);
  15. System.out.println (サフィックスExpressList) ;
  16. System.out.println (calculate(suffixExpressList)) ;
  17. /*
  18. [1, +, (, (, (, 2, +, 3, ), *, 4, ), ), -, 5]
  19. 演算子が存在しません
  20. 演算子が存在しません
  21. [1、2、3、+、4、*、+、5、-]
  22. 16
  23. */
  24. }
  25.  
  26. // 中置式に対応するリストを後置式に対応するリストに変換します
  27. 公共 静的リスト<String> parseSuffixExpressList(リスト<String> ls) {
  28. //2つのスタックを定義する
  29. Stack<String> s1 = new Stack<>(); //シンボルスタック
  30.  
  31. //説明: スタック s2 は変換プロセス全体でポップ操作を行わないため、後で元に戻す必要があります。
  32. // そのため面倒です。ここでは Stack<String> ではなく、List<String> s2 を直接使用します。
  33. //Stack<String> s2 = new Stack<>(); //中間結果を格納するスタック s2
  34. リスト<文字列> s2 = 新しいArrayList<>();
  35. for (文字列項目: ls) {
  36. if (item.matches( "\\d+" )) {
  37. s2.add (アイテム);
  38. }そうでない場合、(item.equals( "(" )) {
  39. s1.push( "(" );
  40. }そうでない場合 (item.equals( ")" )) {
  41. //右括弧の場合)" 、 s1 のスタックの先頭にある演算子が 1 つずつポップアウトされ、左括弧が検出されるまで s2 にプッシュされます。左括弧が検出されると、括弧のペアは破棄されます。
  42. while (!s1.peek().equals( "(" )) {
  43. s2 を追加します(s1 をポップします)。
  44. }
  45. s1.ポップ();
  46. }それ以外{
  47. // 項目の優先度がトップ演算子以下の場合、s1のトップ演算子をポップしてs2にプッシュし、再び(4.1)に戻ってs1の新しいトップ演算子と比較します。
  48. ( s1.size () != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
  49. s2 を追加します(s1 をポップします)。
  50. }
  51. //アイテムをスタックにプッシュする必要もあります
  52. s1.push(アイテム);
  53. }
  54. }
  55. // s1 の残りの演算子をポップアウトして s2 にプッシュします
  56. ( s1.size () != 0 ) の間 {
  57. s2 を追加します(s1 をポップします)。
  58. }
  59. s2を返します
  60. }
  61.  
  62. // 中置式をリストに変換する
  63. 公共 静的リスト<String> toInfixExpressionList(String s) {
  64. リスト<String> ls = 新しいArrayList<>();
  65.  
  66. 整数i = 0;
  67. String str; //複数の数字を連結する
  68. 文字c;
  69. する {
  70. //cが数値でない場合は、lsを直接追加します
  71. ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) < 57) の場合 {
  72. ls.add ( "" + c);
  73. 私は++;
  74. }それ以外{
  75. // 数値の場合は複数桁の問題を考慮する必要があります。
  76. str = "" ;
  77. (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) の場合 {
  78. str + = c;
  79. 私は++;
  80. }
  81. }
  82. } while (i < s.length());
  83. lsを返します
  84. }
  85.  
  86. //逆ポーランド記法に従って評価する
  87. 公共 静的  int計算(リスト<String> ls) {
  88. Stack<String> スタック = new Stack<>();
  89. for (文字列項目: ls) {
  90. //ここでは正規表現を使用して複数桁の数字を抽出します
  91. if (item.matches( "\\d+" )) {
  92. スタックにアイテムをプッシュします。
  93. }それ以外{
  94. int num2 = Integer.parseInt (stack.pop());
  95. int num1 = Integer.parseInt (stack.pop());
  96. 整数res = 0;
  97. スイッチ (アイテム) {
  98. 場合  「+」 :
  99. 数値1と数値2
  100. 壊す;
  101. 場合  「-」
  102. 数値1 - 数値2;
  103. 壊す;
  104. 場合  「*」 :
  105. 数値1と数値2を合計します。
  106. 壊す;
  107. 場合  「/」 :
  108. 数値1/数値2;
  109. 壊す;
  110. デフォルト
  111. 新しい RuntimeException( "演算子エラー" ) をスローします。
  112. }
  113. スタックをプッシュします(res + "" );
  114. }
  115. }
  116. 戻る 整数.parseInt(stack.pop());
  117. }
  118. }
  119.  
  120. //演算子に応じて対応する優先順位番号を返す
  121. クラス操作{
  122. プライベートスタティック 整数 追加= 1;
  123. プライベートスタティック  SUB = 1 ;
  124. プライベートスタティック 整数MUL = 2;
  125. プライベートスタティック 整数DIV = 2;
  126.  
  127. 公共 静的  int getValue(文字列操作) {
  128. int結果 = 0;
  129. スイッチ(操作){
  130. 場合  「+」 :
  131. 結果 = ADD ;
  132. 壊す;
  133. 場合  「-」
  134. 結果 = SUB;
  135. 壊す;
  136. 場合  「*」 :
  137. 結果 = MUL;
  138. 壊す;
  139. 場合  「/」 :
  140. 結果 = DIV;
  141. 壊す;
  142. デフォルト
  143. System.out.println ( "この演算子は存在しません" );
  144. 壊す;
  145. }
  146. 結果を返します
  147. }
  148. }

【編集者のおすすめ】

  1. K8S の基本的なアーキテクチャ概念とネットワーク モデルを理解するのに役立つ 5 分
  2. 1992 年に Baidu のプログラマーが逮捕されたことは、私たちにどのような警告を与えているのでしょうか。
  3. オープンソースのクラウドディスクツール: Nextcloud 21 プライベートクラウドディスク構築
  4. よりクリーンなMicrosoft Windows 10 21H2メジャーアップデートにより、システム内の肥大化したソフトウェアの数が削減されます
  5. 996 作業システムは良いのか悪いのか?

<<:  人工知能は改めてすごいですね!科学者は偶然、死者を「蘇らせる」ことができることを発見した

>>:  柔らかいロボットの進化:優しくて怖い

ブログ    
ブログ    

推薦する

...

...

製造業における人工知能の活用事例トップ 5

製造業は大きなデジタル変革を遂げています。従来のモデルはインダストリー 4.0 へと進化しています。...

ロボットのウォーリーがやってきた!ディズニーは、RLを使って歩くことを学び、社会的にも交流できる新しいロボットを発表した。

チン、チン、チン、『ウォーリー』が舞台に登場!頭は平らで、体は四角い。地面を指差して見るように言うと...

...

あなたの仕事はAIに置き換えられるでしょうか?李開復氏は、これらの4種類の仕事について心配する必要はないと述べている。

[[255576]]最近、李開復氏はタイム誌に「人工知能は強力だが、誤解されている。労働者を守るに...

調査によると、人工知能ソフトウェア市場は2025年までに370億ドルに達すると予想されている。

Forrester は、2025 年までの市場規模をより現実的に把握するために、AI ソフトウェア...

人工知能を無料で学べるトップ 10 ウェブサイト

多くの人が人工知能に非常に興味を持っていますが、どこから始めればよいか分かりません。次に紹介する 1...

2つの主要な負荷分散アルゴリズムの原理に関する研究

負荷分散デバイスの製造は負荷分散アルゴリズムに基づいているため、ここでその原理を調べてみましょう。ポ...

顔認識は数十億ドル規模のブルーオーシャンだが、まだ解決すべき問題が2つある

今日は顔をスキャンしましたか? [[373513]]人工知能の急速な発展により、知能の時代が静かに到...

清華大学特別賞焦建涛のビッグモデル起業:GPT-4ツールの使用における画期的進歩、オープンソースのシードラウンドで7000万ドルの資金調達

清華大学の卒業生 2 人によって作成されたこのツールは、ツールの使用においてGPT-4 の主要な利点...

人工知能の未来とERPシステムの4つの新たな要件

今後 5 年間で、AI は企業とそのビジネス モデルに大きな影響を与えるでしょう。調査会社プライスウ...

...

OpenAIがChatGPT Enterprise Editionをリリース、より高いセキュリティとプライバシー保護を実現

8月29日、OpenAIは、企業ユーザーのニーズを満たし、より高いセキュリティとプライバシー保護を提...