3 2棧的應用舉例

2021-07-26 12:39:15 字數 3923 閱讀 4040

數制轉換

十進位制數n和其他d進製數的轉換是計算機實現計算的基本問題,其解決方法很多,簡單演算法基於下列原理:

n=(n div d)*d+n mod d(其中:div為整除運算,mod為求餘運算)

例如(1348)10=(2504)8

計算過程如下圖:

(這演算法很簡單,在此不做解釋)

我們發現到,對於任意乙個非負整數,它的計算是從低位開始,然後才是高位。所以可以用棧先進後出的規則,下面是**:

演算法3.1:

void conversion (int num) 

while (!stackempty(s))

printf("\n");

} // conversion

現在來分析下:

1.這裡面num是輸入的任意乙個非負十進位制整數。

2.這裡push就是入棧,pop就是出棧,每次把num除以8的餘數入棧,入棧後再把num除以8,這和上面的演算法一樣。

3.stackempty()顧名思義,就是是不是空棧,他的返回值應該是0和非0(c語言沒有bool型別)。

4.隨後用先進後出的思想,就可以實現輸出了。

行編輯程式

當使用者輸入錯誤用「#」表示退格,用「@」表示行無效。

如下圖所示:

下面編寫乙個程式:如果他既不是退格符也不是換行符,則將該字元壓入棧頂;如果是乙個退格符,則從棧頂刪去乙個字元;如果它是乙個退行符,則將字元棧清空為空棧。

演算法如下:

void lineedit() 

ch = getchar(); // 從終端接收下乙個字元

} temp=s.base;

while(temp!=s.top)

// 將從棧底到棧頂的棧內字元傳送至呼叫過程的資料區;

clearstack(s); // 重置s為空棧

printf("\n");

if (ch != eof)

} destroystack(s);

}

下面來分析下:

1.這裡有個eof,注釋為全文結束符,這是乙個巨集,在此程式裡面,我們不必要高畫質這個巨集具體指什麼,只需要知道,有那麼乙個東西即可。

2.getchar這個函式只能接受乙個字元,比如,當你從鍵盤上輸入hjuijij這幾個字母後,只有h被接受,如下圖所示:

3.這個destroystack就是銷毀棧,c/c++的特點就是要及時銷毀不用記憶體。

4.這個程式的思路就是從鍵盤輸入字元,判斷是什麼字元,如果是『#』則棧頂元素出棧,如果是『@』則清空棧,如果是其他字元,則入棧。

迷宮求解

為了保證在任何位置上都能沿原路退回,顯然需要用乙個後進先出的結構來儲存從入口到當前位置的路徑。

下面說明乙個迷宮:

可以寫出如下演算法:

下面說明下這個棧的元素型別的結構體:

typedef structselemtype;
演算法3.2:迷宮maze中存在從入口start到出口end的通道,則求的一條存放在棧中。

下面是**:

status mazepath(mazetype &maze, postype start, postype end)  else  // while

if (e.di<4) // if

} // if

} // else

} while (!stackempty(s) );

return false;

} // mazepath

下面來分析下**:

這個程式的思路如下,postype e,這個是定義了乙個座標型別,變數名為e,並且初始化了棧s,在程式開始(未迴圈時)把座標設定為迷宮開始的位置。並且用了乙個int型的curstep來說明當前的步驟(開始時設定為1)。在do迴圈中,可以看到乙個叫pass的函式,傳遞了乙個引數,為當前位置。

如果可以通過則留下足跡,並且給e進行賦值(e為上面那個結構體selemtype)。這裡我們看到了乙個if(curpos==end)這個,然後我們到倒數第7行看到cusps=nextpos(e.seat,e.di)這個if就是根據他來的。當if(curpos==end)不滿足時,curpos後移,並且cursetp++。

如果不可以通過時,則要先看這個s棧是不是空,不為空這出棧,隨後判斷e.ei==4(這個,其實是標記,上下左右的標記,當此位置上下左右都被標記後就是4)。

差不多就這樣了,大家熟悉下思路就可以了。官方也沒有提供全**,也不好具體分析。

表示式求值

如對下面的算術表示式求值:

4+2*3-10/5

這個表示式的計算順序為:4+2*3-10/5=4+6-10/5=10-10/5=10-2=8

算符優先法就是根據這個運算優先關係的規定來實現對表示式的編譯或解釋執行的。

我們知道算符只有三種關係:

1.低於2.等於3.高於

下面定義了算符之間的這種優先關係。

#是表示式結束符。

為了實現算符優先演算法,可以使用兩個工作棧。乙個叫optr,用以暫存器運算,乙個叫opnd用以寄存運算元或運算結果。思路如下:

1.首先置運算元棧為空棧,表示式起始符「#」為運算子棧底元素;

2.依次讀入表示式中每個字元,若是運算元則進opnd棧,若是運算子則和optr棧的棧頂元素比較優先順序後做相應操作,直至整個表示式求值完畢(即optr棧的棧頂元素和當前讀入的字元均為「#」)

先看乙個例子,再來看**,例子如下:

下面是**:

這**我修改了下,與書上有些地方不同(個人覺得書上的不太好)

operandtype evaluateexpression() 

else

}} return gettop(opnd);

} // evaluateexpression

下面是分析:

這裡兩個棧,optr和opnd,optr存運算子,opnd存數和結果。這裡用nextchar來獲取表示式的字元,這裡有個in函式,其中裡面有個op,就是判斷獲得的這個字元,是不是運算子。這裡還有個operate,這裡的operate不是c++裡面的operate,這個大家就把他理解成乙個運算的函式,他可以把數a和運算子theta和數b進行處理,最後得出結果

思路每次讀取字元,當發現是運算子時放入optr,當是數時放入opnd,還要判斷優先順序,當棧頂優先順序低,則入棧,當相等時(只有棧頂為左括號,待入棧為右括號時才會相等)當棧頂優先順序大的時後著出棧,運算。

棧的應用舉例

一 目的 掌握棧的表示,實現及其針對棧的各種操作進行具體的應用。二 要求 1 建立乙個順序棧,實現括號配對,判斷乙個表示式中括號配對是否合法。2 當使用者輸入乙個合法的表示式後,能夠返回正確的結果。能夠計算的運算子包括 加 減 乘 除 括號 能夠計算的數要求在實數範圍內。對於異常表示式給出錯誤提示。...

棧的應用舉例

十進位制數n和其他d進製數的轉換是計算機實現計算的基本問題,其解決方法很多,其中乙個簡單演算法基於下列原理 n n div d d n mod d 其中 div為整除運算,mod為求餘運算 例如,2007 10 3727 8,其運算過程如下 可以看到上述過程是從低位到高位產生8進製的各個數字,然後從...

棧的應用舉例(三)

struct postype 全值變數 postype begin,end 迷宮的入口座標,出口座標 postype direc 4 移動方向依次為東南西北 define maxlength 25 設迷宮的最大行列為25 typedef int mazetype maxlength maxlengt...