判斷棧的出棧順序是否正確

来源:http://www.cnblogs.com/lovexfr/archive/2016/04/22/5422610.html
-Advertisement-
Play Games

一 問題描述: 兩個數組pPush和pPop分別存儲了壓棧序列和出棧序列,如何判斷出棧序列是否正確,假設元素不重覆。 需要實現的函數: 二 舉例: pPush中序列為:[5 9 1 8 13 4 2 7] 給出一個出棧序列pPop:[8 4 13 1 7 2 9 5],這個出棧序列是正確的。 給出另 ...


 


 

一 問題描述

     兩個數組pPushpPop分別存儲了壓棧序列和出棧序列,如何判斷出棧序列是否正確,假設元素不重覆。

     需要實現的函數:

  bool isStackOutRight(int *stackIn,int *stackOut,int length)

 

 


 

二 舉例:

    pPush中序列為:[5   9   1   8    13     4   2    7]

    給出一個出棧序列pPop[8   4    13   1   7   2  9   5]這個出棧序列是正確的。

    給出另一個出棧序列pPop:[8   4    13   1   5   4   2     7    9]這個出棧序列就是錯誤的,因為8第一個出棧,說明棧中已經壓入過5  9  1三個元素,它們還存在棧中

    它們的出棧順序必須滿足 1  9  5 這個順序(可以不連續,但是19前,95前),但是出棧隊列中給出的順序是1   5   9所以是錯誤的


 

三  演算法思路:

 

     需要用到一個輔助棧stackData來存儲壓入棧而尚未出棧的元素

 

     現在舉錯誤的出棧順序為例:pPop[8   4    13   1   5   4   2     7    9]

   

     1  對出棧序列進行遍歷,第1個元素是8,說明前面已經存過5  9  1,將它存入輔助棧中

          在壓入輔助棧的操作中,我們需要遍歷壓棧序列pPush[5   9   1   8    13     4   2    7]

          (1)   [5   9   1   8    13     4   2    7]   index指向首元素5,不等於元素8 ,將5壓入輔助棧

        (2)   [5   9   1   8    13     4   2    7]   index指向元素9不等於元素8 ,將9壓入輔助棧

          (3)   [5   9   1   8    13     4   2    7]   index指向元素1不等於元素8 ,將1壓入輔助棧

          (4)   [5   9   1   8    13     4   2    7]   index指向元素8等於元素8 ,相等時不壓入,因為還要彈出

          (5)   [5   9   1   8    13     4   2    7]   index指向下一個元素,以便下次壓入操作

           壓棧結束後

 

           stackData:  1  9  5】        (“】”形象的表示棧開口方向向左,1是棧頂元素)  

 

           可以看出,壓入輔助棧的關鍵是壓棧序列中的元素是否等於目前的遍歷元素(8),不等於壓入,等於就不再壓入 

 

     2  遍歷第2個元素是4,它不等於stackData中的top元素1,說明它可能(也可能存在於輔助棧)是新壓入的元素,那麼容易知道4之前的元素13已經被壓入棧中,所以將13壓入輔助棧

 

          stackData:   13  1  9  5】 

 

           index指向下一個元素2

             [5   9   1   8    13     4   2    7]

 

     3  遍歷第3個元素是13,它等於是stackData中的top元素13,說明沒有新壓入元素,只是彈出元素,所以輔助棧需要彈出top元素13

 

          stackData:  1  9  5】     

 

    4  遍歷第4個元素是1,它等於現在stackData中的top元素1,說明沒有新壓入元素,只是彈出元素,所以輔助棧需要彈出top元素1

 

         stackData:    9  5】     

 

   5  遍歷第5個元素是5,它不等於現在stackData中的top元素9,說明它可能是新壓入的元素,也可能是輔助棧中的元素

          情況1:如果是新壓入的元素,那麼出棧順序到現在為止還是正確的

           情況2:如果是輔助棧中的元素(已經知道不是首元素),就可以知道出棧序列是錯誤的,因為如果是輔助棧中的元素,出棧順序必須和輔助棧一致,也就是必須是先95

           問題的關鍵是怎麼判斷這種情況是情況1還是情況2

         可以這樣做,將這種情況看做是情況1,那麼需要繼續向輔助棧中壓入元素,但是會發現將壓棧序列中全部元素都壓入輔助棧後依然找不到一個元素等於當前遍歷元素5   

           在第2步後,index已經指向了2

         (1)   [5   9   1   8    13     4   2   7]   index指向元素2不等於元素5 ,將2壓入輔助棧

          (2)   [5   9   1   8    13     4   2    7]   index指向元素7不等於元素5 ,將7壓入輔助棧

           現在index已經指向了最後一個元素,但是沒有找到等於5的元素,那麼可以斷言,5其實是在輔助棧中的,這種情況屬於情況2,因此出棧序列是不正確

         

   


 

四   偽代碼

     int index = 0

       for 遍歷出棧序列           

             if  (輔助棧不空 && 輔助棧top元素等於pPop[i])                  

                      輔助棧彈出top元素

             else    //輔助棧為空 或者 top元素不等於pPop[i],要壓入元素了

                  while(pPush[index] 不等於 pPop[i] //只壓入pPop[i]之前的元素,本身不壓入

                         輔助棧壓入pPush[index] 元素 

                         index++

                   if (index 等於 length)//說明沒有找到這個元素標記,pPop[i]一定在輔助棧中,出棧序列錯誤

                             return false

                   else

                             index++ //要指向下一個元素

 

       return  true  //for 迴圈能正常結束,出棧序列就一定是正確的

 


 

 五  代碼

       1   C++版本

  

 1 bool isStackOutRight(int *stackIn,int *stackOut,int length){    
 2       stack<int>  stackData;//輔助棧
 3       int index(0);        
 4          for (int i = 0;i<length;i++){//遍歷整個出棧序列
 5   
 6              if (!stackData.empty() && stackData.top() == stackOut[i]) //輔助棧不空,而且遍歷的元素是輔助棧的top元素,需要彈出操作             
 7                      stackData.pop();                                     
 8              else {  //輔助棧為空,或者不等於首元素,指向壓棧操作
 9                  while(index<length && stackIn[index] != stackOut[i])
10                     stackData.push(stackIn[index++]);
11                 if (index == length)//這裡是關鍵,說明在壓棧序列中從index開始往後遍歷,沒有找到該元素,該出棧序列不正確
12                     return false;
13                 else 
14                     index++;
15             }
16         }
17         return true;//整個for迴圈能正常結束(沒有遇到return false),說明出棧序列正確
18  }

 

 

 

           

     

 


 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 註:以下文章原文來自於Dr Charles Severance 的 《Python for Informatics》 本書中的許多例子關註的是讀取文件並查找數據,但在互聯網中還有許多不同信息源。 本章我們將偽裝成瀏覽器用超文本傳送協議(HTTP)從網站獲取網頁,通讀並分析它。 12.1 超文本傳送協 ...
  • 引言 - 為尋一顆明星 { 風 : http://music.163.com/#/song?id=5276735 } 前言 - 有點扯 C基本是程式生涯的入門語言. 雖說簡單, 但已經斷層了. 估計是不合時宜吧. 工作中也就在網路層框架會看見部分C的影子. 自己用C開發久了, 發現C一個弊端是 當一 ...
  • 問題的描述: 一個項目,涉及到了 兩個數據源,分別使用的是 兩個不同的 資料庫連接池,其中一個是 poxool 連接池,問題在於,spring在啟動時,只初始化其中的一個 資料庫連接池中的資料庫連接,而 poxool配置的資料庫連接池,在啟動時 沒有進行初始化,一個資料庫連接也沒有初始化好,所以導致 ...
  • 本文章向碼農介紹Typecho 博客文章瀏覽次數統計插件Stat,需要的碼農可以參考一下。 我的新博客使用的博客系統是Typecho博客系統,使用的時候發現,該博客系統本身沒有文章瀏覽統計功能,很不習慣。在網上搜了下後發現,有相關的博客插件可以實現,插件的使用很簡單,博客吧在這裡簡單說明下Typec ...
  • 第一步:配置防火牆(預設情況下,埠80和3306是拒絕訪問的,在防火牆上進行配置): vi /etc/sysconfig/iptables(在"COMMIT"的上一行加上如下兩句) -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j  ...
  • Delphi XE10支持MongoDB的資料庫,提供了個例子restaurants可批量導入數據。 本文對比Delphi例子與MongoDB自帶的mongoimport導入批量數據的性能。 步驟: 1.運行例子前需要先安裝MongoDB, MongoDB安裝及運行mongod.exe,安裝完成後b ...
  • 控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向對象編程的法則來削減電腦程式的耦合問題,也是輕量級的Spring框架的核心。 控制反轉一般分為兩種類型,依賴註入(Dependency Injection,簡稱DI)和依賴查找。依賴註入應用比較廣泛。把控制權從具 ...
  • 概述 elixir 本身是一種 immutable 的語言,預設情況下,進程間是不共用任何狀態的,進程之間通過消息來交互。 而 Agent 則封裝了一種進程間共用狀態的方式,通過這種方式,不用顯式的寫 send/receieve 的代碼,就能方便的在進程之間共用狀態。 使用方法 不用 Agent 來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...