(1)先说说这两个星期的收获
学了栈和队列的相关内容,但是对栈比较熟,队列还需要多熟悉一下,学了发现和前面的顺序表的结构还是很像的。
(2)上次的目标:
全部没有达到,对时间的安排不合理,作业堆在一个星期完成,大大降低效率,希望下个星期不要再这样了,要留多点时间研究透题目和自己代码的错因。
(3)这周的作业编程题:
题目:括号匹配
给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。
输入格式:
输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。
输出格式:
如果括号配对,输出yes,否则输出no。
代码:
#include
#include
#include
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
typedef char SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;//顺序栈定义
//顺序栈的初始化
Status InitStack(SqStack &S)
{// 构造一个空栈 S
S.base = new SElemType[MAXSIZE]; //为顺序栈分配一个最大容量为MAXSIZE的数组空间
if(!S.base)
exit (OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
//顺序栈的入栈
Status Push(SqStack &S,SElemType &e)
{ // 插入元素e为新的栈顶元素
if(S.top-S.base==S.stacksize)
return ERROR; //栈满
*(S.top++) = e; //元素e压入栈顶,栈顶指针加1
return OK;
}
// 顺序栈的出栈
Status Pop(SqStack &S,SElemType &e)
{// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(S.base == S.top)
return ERROR;//栈空
e = *(--S.top); //栈顶指针减1,将栈顶元素赋给e
return OK;
}
//取顺序栈的栈顶元素
Status GetTop(SqStack S,SElemType &e)
{// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top == S.base)
return ERROR;
e = *(S.top-1);//栈顶指针减1,将栈顶元素赋给e
return OK;
}
int main()
{
string s;
getline(cin,s); //getline()获取一行输入,包括空格
int len=s.size(); //获取输入字符的长度
SqStack S;
SElemType temp;
InitStack(S);
int flag = 1; //判断匹配是否成功
for(int i = 0; i < len; i++) {
SElemType e;
switch (s[i]){
case '[':
case '(':
case '{':
Push(S, s[i]); //左括号入栈
break;
case ')' :
if (GetTop(S, e) && e == '(') //栈非空且取出的栈顶元素为(
Pop(S, e); //匹配成功,(出栈
else
flag=0; //匹配失败
break;
case ']' :
if (GetTop(S, e) && e == '[') //栈非空且取出的栈顶元素为[
Pop(S, e); //匹配成功,[出栈
else
flag=0; //匹配失败
break;
case '}' :
if (GetTop(S, e) && e == '{') //栈非空且取出的栈顶元素为{
Pop(S, e); //匹配成功,{出栈
else
flag=0; //匹配失败
break;
}
}
if(flag && GetTop(S, temp) == ERROR) //栈为空 说明所有的括号匹配成功
cout << "yes";
else
cout << "no";
return 0;
}
分析如代码中的注释所示
遇到的困难:
(1) 改错的能力差,要像老师说的那样,遇到代码出错时要通过多写注释,运用cout一些标记的方法来分析,我写了很多个版本,有些版本还没找出错误就放弃了,这是不行的,应该通过改到对为止来发现自己的错误
(2) 头文件部分不熟,经常乱用或少用
(3) Getline()和cin的用法区别还没有分清;
(4) 有一些低价错误要避免,true因为写成ture而导致出错。
(5) if,elseif,switch用法还不熟
(6) if,else语句后有两条以上语句 要加{}!!经常出错
实践题:
题目:设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格
代码:
#include
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int QElemType;
typedef int Status;
typedef struct QNode{
QElemType data;
QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
// 链队的初始化
Status InitQueue(LinkQueue &Q)
{// 构造一个空队列Q
Q.front = new QNode;
if(Q.front == NULL)
{
return OVERFLOW; // 存储分配失败
}
Q.front->next = NULL;
Q.rear = Q.front;
return OK;
}
// 链队的入队
Status EnQueue(LinkQueue &Q,QElemType e)
{ // 插入元素e为Q的新的队尾元素
QNode *p = new QNode;
if(p == NULL)
{
return OVERFLOW;// 存储分配失败
}
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p; // 修改队尾指针
return OK;
}
// 链队的出队
Status DeQueue(LinkQueue &Q,QElemType &e)
{//删除Q的队头元素,用e返回其值,并返回OK
if(Q.front == Q.rear)
{
return ERROR; //若队列空,则返回 ERROR
}
QNode *p = Q.front->next;//p指向队头元素
e = p->data;//e保存队头元素的值
Q.front->next = p->next;//修改头指针
if(Q.rear == p)
{
Q.rear = Q.front;//最后一个元素被删,队尾指针指向头结点
}
delete p;
return OK;
}
int main()
{
LinkQueue A, B; // 新建两个队列
InitQueue(A); // 初始化队列
InitQueue(B);
int n;
cin >> n; // 顾客数量
int a[n];
for(int i = 0; i < n; i++)
{
cin >> a[i];
if (a[i] % 2 == 1) // 奇数顾客入队
EnQueue(A, a[i]);
else // 偶数顾客入队
EnQueue(B, a[i]);
}
int flag = 0; // 判断是否第一个顾客
for(int i = 0; i < 1000; ++i)
{
/*
A队出两个,B队出一个的第一个关键之处
temp必须放进for循环,每一次循环都会初始化,失去之前的赋值
相当于每次循环都重新声明temp这个变量
*/
QElemType temp;
if(DeQueue(A, temp) == OK) // A队列非空
{
if(flag == 0) // 第一个顾客
cout << temp; // 输出没有空格
else
cout << " " << temp; // 之后的顾客都先输出空格再输出顾客编号
flag = 1;
}
/*
A队出两个,B队出一个的第二个关键之处
整个for循环里面有两个if判断,第一个if判断只要A队列非空就可以输出
第二个if判断必须B队列非空且隔一次输出
简单来说就是
i = 0:A
i = 1:A B
i = 2:A
i = 3:A B
以此类推,输出就是A A B A A B .... 直到输出完所有编号
*/
if(i % 2 == 1 && DeQueue(B, temp) == OK)
{
if(flag == 0)
cout << temp;
else
cout << " " << temp;
flag = 1;
}
}
return 0;
}
遇到的问题:
(1) 依旧是改错能力差
(2) 分类讨论考虑不全,容易想复杂
下周目标:
作业提前写,不要都堆在最后一天
坚持一个方法就不要变,要通过不断改正发现自己的问题
一道题有多种解法,每一种都去试一下。