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技術がピカソの隠された絵画の発見を助ける

[[429170]]最近、外国メディアの報道によると、有名になる前のパブロ・ピカソは、必ずしも画材を...

お伝えする 5 つの理由: セキュリティ監視はなぜ人工知能なしでは実現できないのか?

人工知能は、特にセキュリティ分野において業界に大きな影響を与え始めています。成熟したセキュリティ サ...

清華大学とアイデアルは、自動運転機能を向上させる視覚言語モデルDriveVLMを提案した。

生成AIと比較して、自動運転も近年AIの研究開発が最も活発に行われている分野の1つです。完全自動運転...

Appleのアプリランキングアルゴリズム調整の裏側:ランキング管理企業が一夜にして沈黙

4月1日早朝のニュース:3月初旬から、AppleはAppランキングアルゴリズムを徐々に調整し、ランキ...

...

偉大な人物が学界に復帰:何開明氏がMITへの入学を発表

「FAIR研究科学者として、私は2024年にMITのEECS教授陣に加わります。」 AI分野の著名な...

ドローンは都市の発展を助け、6つの側面でインテリジェントな変化をもたらす

近年、国民の高品質・高水準の都市生活への絶え間ない追求に応えるため、スマートシティ建設が大きな注目を...

50歳の男性がAIの博士号を取得するためにケンブリッジに戻り、AIを使ってレタスを収穫するロボットを開発した。

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...

BEV におけるデータセット間レーダーカメラ融合に関する実験的研究

この記事は、Heart of Autonomous Driving の公開アカウントから許可を得て転...

RPA 導入が失敗する 7 つの理由

ロボティック・プロセス・オートメーションは現在、業界全体のデジタル化を推進するデジタル変革の中核とな...

「リーフチップ」が小型ロボットに油圧パワーを提供

[[186706]]マサチューセッツ工科大学(MIT)は最近、同校の研究者らが樹木や植物のポンプ機構...

ディープラーニングの仕組み: 今日の AI を支えるニューラル ネットワークの内部を覗いてみよう

[[428985]] [51CTO.com クイック翻訳]今日の人工知能の繁栄は、人工ニューラルネッ...

LLM幻覚問題の徹底レビュー! HITチームの50ページのレビューが公開された

幻覚だよ、古い友人よ。 LLM が私たちの視野に入って以来、錯覚の問題は常に無数の開発者を悩ませてき...