棧和隊列
思維導圖
PTA實驗作業
2.1 題目一:7-3 表達式轉換
- 算術表達式有前綴表示法、中綴表示法和后綴表示法等形式。日常使用的算術表達式是采用中綴表示法,即二元運算符位於兩個運算數中間。請設計程序將中綴表達式轉換為后綴表達式。
2.2 設計思路
/*表達式轉換*/
定義運算符棧指針 *optr
定義字符串數組 exp 存儲中綴表達式
定義字符串數組 polish 存儲逆波蘭表達式
while 從exp讀取字符ch and ch!=\0'
if ch 為數字
then 將后續的所有數字均依次存放到 polish, 並以字符#標志數值串結束
if ch = ')'
then 將 optr 遇到第一個 ‘(' 以前的運算符出棧放入polish,並將 '(' 出棧
if ch = '+ ' or '-'
then 出棧運算符直至棧空或者棧頂為 ’( ‘ ,並存放到postexp中,將+'或-進棧
if ch = '*' or '/ '
then if 棧頂 = ' * ' 或 ' / '
then 出棧直到棧頂不是 ' * ' 或 ' / '
else 入棧
end
將 optr 中所有運算符依次出棧並存放到 polish 中
2.3 實驗代碼
- 轉換函數
- 輸出函數
2.4 遇到的問題及解決方法:
- 格式錯誤:沒有考慮到數字為多位數時的情況
解決方法:在一個連續數字輸入后添加 ’#‘ 作為標識 - 答案錯誤:運算數前有正負號
解決方法:若 ’+‘ ’-‘ 號前不是數字,即為正負號,添加代碼if( '(' == *(exp-1) || '+' == *(exp-1) ||'-' == *(exp-1) ||'*' == *(exp-1) || '/' == *(exp-1)|| i==0 )
進行判斷 - 答案錯誤:有非整數情況出現
解決方法: 將while( *exp >= '0' && *exp <= '9')
修改為while( *exp >= '0' && *exp <= '9' || '.' == *exp )
2.1 題目二:7-2 符號配對
請編寫程序檢查C語言源程序中下列符號是否配對:/與/、(與)、[與]、{與}。
2.2 設計思路
while true
按行輸入並保存至字符串數組 str
if str[0] = ' . ' and str 的長度為1
then break
if str[i] 為 ' /* ' or ' ( ' or ' [ ' or ' { '
then 入棧
if str[i] 為 ’ */ ' or ' ) ' or ' ] ' or ' } '
then 出棧並判斷是否匹配,不匹配時跳出循環
end
2.3 實驗代碼
2.4 遇到的問題及解決方法:
- 編譯錯誤:函數在定義前沒有先聲明
解決方法:函數應該先聲明再定義 - 答案錯誤:開頭有多余左符號
解決方法:沒有判斷只輸入一個符號的情況下的不匹配,添加代碼進行判斷 - 段錯誤:達到最大值,但不匹配
解決方法:定義的字符串數組過小,改為#define MAXSIZE 100
2.1 題目三:7-2 銀行業務隊列簡單模擬
設某銀行有A、B兩個業務窗口,且處理業務的速度不一樣,其中A窗口處理速度是B窗口的2倍 —— 即當A窗口每處理完2個顧客時,B窗口處理完1個顧客。給定到達銀行的顧客序列,請按業務完成的順序輸出顧客序列。假定不考慮顧客先后到達的時間間隔,並且當不同窗口同時處理完2個顧客時,A窗口顧客優先輸出。:
2.2 設計思路
for i=0 to n
if 客戶為奇數
then 入 q1 隊
else 入 q2 隊
end
while q1 不空 and q2 不空
q1 出隊兩次並輸出
q2 出隊一次並輸出
end
while q1 不空 or q2 不空
q1 or q2 逐個出隊
end
2.3 實驗代碼
2.4遇到的問題及解決方法:
- 答案錯誤:最小N
解決方法:沒有判斷 q1 第二次出隊時是否為空,添加代碼if( !q1.empty() ) { print(q1.front()); q1.pop(); }
- 格式錯誤:沒有達到 數字間以空格分隔,但最后一個編號后不能有多余的空格 的要求
解決方法:通過百度了解,可以增加一個輸出函數用於判斷是否為首元素
3. 本周題目集的PTA最后排名
本次2個題目集總分:206
3.1棧PTA排名
3.2隊列PTA排名
3.3 我的總分:2分
4.閱讀代碼
使用兩個隊列實現一個棧 :
具體代碼實現
public class StackByTwoQueue {
private LinkedList<String> queue1 = new LinkedList<String>();
private LinkedList<String> queue2 = new LinkedList<String>();
/*
* 兩個隊列實現一個棧
* pop完成出棧操作,push完成入棧操作
*/
public void push(String obj) {
if(queue1.isEmpty()){
queue2.add(obj);
}
if(queue2.isEmpty()){
queue1.add(obj);
}
}
public String pop() {
//兩個棧都為空時,沒有元素可以彈出
if (queue1.isEmpty()&&queue2.isEmpty()) {
try {
throw new Exception("stack is empty");
} catch (Exception e) {
}
}
if(queue1.isEmpty()){
while(queue2.size()>1){
queue1.add(queue2.poll());
}
return queue2.poll();
}
if(queue2.isEmpty()){
while(queue1.size()>1){
queue2.add(queue1.poll());
}
return queue1.poll();
}
return null;
}
public static void main(String[] args) {
StackByTwoQueue stack = new StackByTwoQueue();
for(int i=0;i<10;i++){
stack.push(i+"");
}
for(int i=0;i<20;i++){
System.out.println(stack.pop());
}
}
}
- 此代碼實現的時用兩個隊列來實現棧,網上關於這個題目的代碼基本上都是c++,代碼雖然不能完全理解,但思路還是可以明白的。將queue1 作為入隊存儲數據的功能,queue2 作為中轉件,出隊時先把 queue1 中數據取出然后加入到 queue2 中,出隊之后再返回到 queue2 中。