栈和队列
思维导图
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 中。