Java プログラミング スキル - データ構造とアルゴリズムの「スタック」

Java プログラミング スキル - データ構造とアルゴリズムの「スタック」

[[387145]]

基本的な紹介

1. スタックはFILO(先入れ後出し)順序付きリストです

2. スタックは、線形テーブル内の要素の挿入と削除を、線形テーブルの同じ端でのみ実行するように制限する特殊な線形テーブルです。挿入と削除を許可する端は可変端で、スタックの上部と呼ばれ、もう一方の端は固定端で、スタックの下部と呼ばれます。

3. スタックの定義によれば、スタックに最初に配置された要素はスタックの一番下に配置され、スタックに最後に配置された要素はスタックの一番上に配置されます。要素を削除する場合はその逆になります。スタックに最後に配置された要素が最初に削除され、スタックに最初に配置された要素が最後に削除されます。

スタックの応用シナリオ

1. サブルーチン呼び出し:サブルーチンを呼び出す前に、次の命令のアドレスをスタックに格納し、サブルーチンの実行後にアドレスを取り出して元のプログラムに戻ります。

2. 再帰呼び出しを処理する: サブルーチン呼び出しに似ていますが、次の命令のアドレスを保存するだけでなく、パラメーター、ローカル変数、その他のデータもスタックに保存します。

3. 式の変換(中置式から後置式へ)と評価(実際の解)。

4. 二分木の走査。

5. グラフの深さ優先探索アルゴリズム。

スタック構造の実装例

  1. パッケージ com.structures.stack;
  2.  
  3. java.util.Scanner をインポートします。
  4.  
  5. パブリッククラスArrayStackDemo {
  6. 公共 静的void main(String[] args) {
  7. ArrayStack スタック = 新しいArrayStack(4);
  8. 文字列キー= "" ;
  9. ブールループ = true ;
  10. スキャナー scanner = new Scanner( System.in );
  11. while (ループ) {
  12. System.out.println ( "show: スタックを表示" );
  13. System.out.println ( "exit: プログラムを終了" );
  14. System.out.println ( "push: スタックにデータを追加します (push)" );
  15. System.out.println ( "pop: スタックからデータを取り出す (pop)" );
  16. キー= スキャナ.next ( );
  17. スイッチ(キー){
  18. 場合  "見せる"
  19. スタックリスト();
  20. 壊す;
  21. 場合  "押す"
  22. System.out.println ( "数字を入力してください" );
  23. int値 = scanner.nextInt();
  24. スタックに値をプッシュします。
  25. 壊す;
  26. 場合  「ポップ」 :
  27. 試す {
  28. int res = stack.pop();
  29. System.out.println ( "スタックからデータがポップされました%d\n" +res);
  30. } キャッチ (例外 e) {
  31. System.out.println (e.getMessage()) ;
  32. }
  33. 壊す;
  34. 場合  "出口"
  35. スキャナーを閉じます() ;
  36. ループ = false ;
  37. 壊す;
  38. }
  39. }
  40. System.out.println ( "プログラムが終了します" ) ;
  41. }
  42. }
  43.  
  44. //スタック構造を表すクラスを定義する
  45. クラスArrayStack {
  46. private int maxSize; //スタックサイズ
  47. private int [] stack; //配列はスタックをシミュレートし、データは配列内に配置されます
  48. プライベートint   top = -1; // top はスタックの先頭を意味し、-1 に初期化されます
  49.  
  50. パブリックArrayStack( int最大サイズ){
  51. this.maxSize = 最大サイズ;
  52. スタック = 新しいint [this.maxSize];
  53. }
  54.  
  55. // スタックがいっぱいかどうか確認する
  56. パブリックブール値isFull() {
  57. 戻る 上部== 最大サイズ - 1;
  58. }
  59.  
  60. // スタックが空かどうか確認する
  61. パブリックブール値isEmpty() {
  62. 戻る == -1;
  63. }
  64.  
  65. //スタックにプッシュ
  66. パブリックvoidプッシュ( int値){
  67. 満杯の場合(){
  68. System.out.println ( "スタックがいっぱいです" ) ;
  69. 戻る;
  70. }
  71. トップ++;
  72. スタック[上部] = 値;
  73. }
  74.  
  75. //ポップアウト
  76. 公共 整数ポップ() {
  77. 空の場合(){
  78. 新しい RuntimeException( "スタックが空です" ) をスローします。
  79. }
  80. int値 = スタック[上部];
  81. トップ--;  
  82. 戻り値;
  83. }
  84.  
  85. //スタックの状況を表示する [スタックを走査する]
  86. パブリックボイドリスト(){
  87. 空の場合(){
  88. System.out.println ( "スタックは空です、データがありません~~" );
  89. 戻る;
  90. }
  91. ( int i = top ; i >= 0; i --) {  
  92. システム.out.printf ( "stack[%d]=%d\n" , i, stack[i]);
  93. }
  94. }
  95.  
  96. }

スタックを使用して式の計算を完了する(中置式)

数字スタックとシンボルスタックの 2 つのスタックを準備します。

1. インデックス値 (index) を介して式を走査します。

2. 数字であることが判明した場合、それは直接デジタルスタックに格納されます。

3. シンボルの場合は、状況を個別に考慮します。現在のシンボルスタックが空の場合は、ステーションに直接入力します。シンボルスタックに演算子がある場合は、それを比較します。

  • 現在の演算子の優先度がスタック内の演算子の優先度以下の場合は、数値スタックから 2 つの数値をポップし、次にシンボル スタックから文字をポップして演算を実行し、その結果を数値スタックに入力してから、現在の演算子をシンボル スタックに入力します。
  • 現在の演算子の優先度がスタック内の演算子よりも高い場合は、その演算子はスタックに直接プッシュされます。

4. 式をスキャンすると、対応する数字と記号が数字スタックと記号スタックから順番にポップされ、実行されます。

5. 最後に、数値スタックには式の結果である数値が 1 つだけ残ります。

  1. パッケージ com.structures.stack;
  2.  
  3. パブリッククラス Calculator {
  4. 公共 静的void main(String[] args) {
  5. //表現
  6. 文字列式 = "700+2*6-2" ;
  7. //スタックをカウントする
  8. ArrayStack2 numStack = 新しいArrayStack2(10);
  9. //シンボルスタック
  10. ArrayStack2 operStack = 新しいArrayStack2(10);
  11. 整数  index = 0; // スキャン用
  12. 整数1 = 0;
  13. 整数2 = 0;
  14. 整数オペランド = 0;
  15. 整数res = 0;
  16. char ch = ' ' ; //スキャンした各文字を ch に保存します
  17. String keepNum = "" ; //複数の数字を連結するために使用します
  18. )の間{
  19. ch =式.部分文字列(インデックス,インデックス+ 1 ).charAt(0);
  20. //演算子の場合
  21. オペランドスタックがオペランドスタックである場合、
  22. //空の場合
  23. (operStack.isEmpty())の場合{
  24. operStack.push(ch);
  25. }それ以外{
  26. operStack.priority(ch) <= operStack.priority(operStack.peek()) の場合 {
  27. num1 = numStack.pop();
  28. num2 = numStack.pop();
  29. oper = operStack.pop();
  30. res = numStack.cal(num1, num2, oper);
  31. //演算結果を数値スタックに、現在のシンボルをシンボルスタックに格納します
  32. numStack.push(res);
  33. operStack.push(ch);
  34. }それ以外{
  35. operStack.push(ch);
  36. }
  37. }
  38. }それ以外{
  39. // 複数桁の数字を扱う場合、すぐにスタックにプッシュすることはできません。
  40. 数値を保持 += ch;
  41. //chが式の最後の桁の場合
  42. if (インデックス== 式の長さ() - 1 ) {
  43. numStack.push(整数.parseInt(keepNum));
  44. }それ以外{
  45. if (operStack.isOper(式.部分文字列(インデックス+1,インデックス+2).charAt(0))) {
  46. numStack.push(整数.parseInt(keepNum));
  47. 保持数 = "" ;
  48. }
  49. }
  50. }
  51. インデックス++;
  52. //最後までスキャンして終了
  53. if (インデックス>= 式の長さ()) {
  54. 壊す;
  55. }
  56. }
  57. )の間{
  58. (operStack.isEmpty())の場合{
  59. 壊す;
  60. }
  61. num1 = numStack.pop();
  62. num2 = numStack.pop();
  63. oper = operStack.pop();
  64. res = numStack.cal(num1, num2, oper);
  65. numStack.push(res);
  66. }
  67. System.out.printf ( "expression%s=%d\n" ,expression,numStack.pop());
  68.  
  69. }
  70. }
  71.  
  72. クラスArrayStack2 {
  73. private int maxSize; //スタックサイズ
  74. private int [] stack; //配列はスタックをシミュレートし、データは配列内に配置されます
  75. プライベートint   top = -1; // top はスタックの先頭を意味し、-1 に初期化されます
  76.  
  77. パブリックArrayStack2( int最大サイズ){
  78. this.maxSize = 最大サイズ;
  79. スタック = 新しいint [this.maxSize];
  80. }
  81.  
  82. //スタック上の現在の値を返す(ポップしない)
  83. 公共  intピーク() {
  84. スタック[先頭]を返します
  85. }
  86.  
  87. // スタックがいっぱいかどうか確認する
  88. パブリックブール値isFull() {
  89. 戻る 上部== 最大サイズ - 1;
  90. }
  91.  
  92. // スタックが空かどうか確認する
  93. パブリックブール値isEmpty() {
  94. 戻る == -1;
  95. }
  96.  
  97. //スタックにプッシュ
  98. パブリックvoidプッシュ( int値){
  99. 満杯の場合(){
  100. System.out.println ( "スタックがいっぱいです" ) ;
  101. 戻る;
  102. }
  103. トップ++;
  104. スタック[上部] = 値;
  105. }
  106.  
  107. //ポップアウト
  108. 公共 整数ポップ() {
  109. 空の場合(){
  110. 新しい RuntimeException( "スタックが空です" ) をスローします。
  111. }
  112. int値 = スタック[上部];
  113. トップ--;  
  114. 戻り値;
  115. }
  116.  
  117. //スタックの状況を表示する [スタックを走査する]
  118. パブリックボイドリスト(){
  119. 空の場合(){
  120. System.out.println ( "スタックは空です、データがありません~~" );
  121. 戻る;
  122. }
  123. ( int i = top ; i >= 0; i --) {  
  124. システム.out.printf ( "stack[%d]=%d\n" , i, stack[i]);
  125. }
  126. }
  127.  
  128. //演算子の優先度を返します。数値が大きいほど優先度が高くなります。
  129. //現在使用できる演算子は + - * / のみであると仮定します。
  130. 公共  int優先度( intオペランド) {
  131. 演算子 == '*' || 演算子 == '/'の場合{
  132. 1 を返します
  133. }そうでない場合 (oper == '+' || oper == '-' ) {
  134. 0を返します
  135. }それ以外{
  136. -1 を返します
  137. }
  138. }
  139.  
  140. // 演算子かどうかをチェックする
  141. パブリックブールisOper( char val) {
  142. val == '+' || val == '-' || val == '*' || val == '/'返します
  143. }
  144.  
  145. //計算方法
  146. 公共  int cal( int num1, int num2, int oper) {
  147. 整数res = 0;
  148. スイッチ(オペランド){
  149. 場合  '+' :
  150. 数値1と数値2
  151. 壊す;
  152. 場合  '-' :
  153. res = num2 - num1; //順序に注意
  154. 壊す;
  155. 場合  '*' :
  156. 数値1と数値2を合計します。
  157. 壊す;
  158. 場合  '/' :
  159. res = num2 / num1; //順序に注意
  160. 壊す;
  161. }
  162. resを返します
  163. }
  164. }

【編集者のおすすめ】

  1. いいですね、上司からシンプルなワークフロー エンジンを開発するように言われました...
  2. Windows 10 は世界を揺るがす変化をもたらします!今年最初のアップデートが来ました
  3. 2021年に注目すべき6つのサイバーセキュリティトレンド
  4. 近年の Windows 10 における最大の改善点! Windows 10 21H2 新機能プレビュー
  5. Xiao Aiは本当にPC版をリリースしたのか?コンピュータ版のXiao Aiを体験してみましょう

<<:  2つのセッションが終了しました!自動運転に関する15の提案

>>:  ケータリングロボットが市場発展の時代を先導

ブログ    
ブログ    

推薦する

AI はフロントエンドコードを生成できますか?

この号で共有されているのは、AIGC の用途の 1 つは、フロントエンド コードの作成または生成を支...

機械学習は「部屋の中の象」に対処するのが難しい

AI には、部屋に突然象が現れたなど、信じられないような異常を発見しながらも、それを冷静に受け入れる...

2017 年の機械学習開発に関するトップ 10 の予測: 悲観的か現実的か?

「分析の時代」はまだ始まったばかりですが、私たちには多くの刺激的なアイデアと期待がもたらされていま...

Google、ファイルサイズを35%削減できる新しいJPEGアルゴリズムをオープンソース化

海外メディアの報道によると、Googleはファイルサイズを約35%削減、あるいはファイルサイズを変え...

シリコンバレーの大企業も「名門校の学位」を重視するのでしょうか? Redditの男の魂を問う質問が白熱した議論を巻き起こす

シリコンバレーの大企業からのオファーは多くのプログラマーにとって依然として非常に魅力的であり、今年は...

...

機械学習とデータサイエンスに関する必読の無料オンライン電子書籍 10 冊

KDnuggets 編集者の Matthew Mayo が、機械学習とデータ サイエンスに関連する書...

MIT テクノロジーレビュー: 6 つの質問が生成 AI の未来を決定する

「生成AIは2023年に世界を席巻します。その未来、そして私たちの未来は、私たちの次の一手によって決...

MSRAがACM TOMM 2017最優秀論文賞を受賞: 複雑でプロフェッショナルなグラフィックデザイン作業をAIに任せよう

豊富な写真と美しいレイアウトで記事を作成、編集する方法に悩んだことはありませんか?あるいは、芸術的な...

何?ニューラルネットワークは新しい知識も生み出せるのでしょうか?

作業を実行するための明示的なアルゴリズムを知らなくても、特定のタスク用にニューラル ネットワーク (...

社会的関心の強化に基づくビデオ推奨アルゴリズム

1. 推奨ステータスまず、レコメンデーションシステムの現状について簡単に紹介します。推薦システムは、...

人工知能

[[200702]] 250年以上にわたり、技術革新は経済発展の根本的な原動力となってきました。これ...

人工知能とビッグデータがビジネス環境をどう変えるのか

人々がビジネスを行うようになって以来、ビジネスを強化するためにテクノロジーが活用されてきました。 1...

...

Nvidiaの次世代GPUが発表、H100を超える!最初の3nmマルチチップモジュール設計は2024年にデビュー予定

3nmプロセス、H100をはるかに超える性能!つい最近、海外メディアのDigiTimesが、コードネ...