第三章主要学了栈与队列,其定义,实现,操作。还有可怕的递归算法,以前感觉没什么,现在发现挺有用的,可以不用很复杂的代码解决挺复杂的问题(虽然时间效率有点低,会出现重复的子问题)。
栈可以看成一个容器,先进后出。队列则可以看成一个管道,先进先出。实质大概都是顺序表与链表。在操作顺序栈和顺序队列时要判断其满或空。
另外看到了一个循环队列:通过取模使得头指针和尾指针相接,非常巧妙。取模在c++中是一个很重要的思想,很多巧妙的方法都由其而来。
接下来是作业:括号匹配一开始自己打的时候漏洞频出,毕竟书上的和实际跑起来的代码还是有很大的区别。后来通过老师的讲解慢慢实现了出来。主要1.cin.getline的读取方式2.通过设立一个Flag将多个出口统一起来3.回车在这之中会自对转换为\0。
1.给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。
输入格式:
输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。
输出格式:
如果括号配对,输出yes,否则输出no。
#include#include using namespace std; #define Max_size 150 //最大容量typedef char data;typedef struct{ data SElemType[Max_size]; int top; }stack; //定义栈 void initial(stack &st){ st.top = 0;} //初始化栈void push(stack &st, data x){ st.SElemType[st.top] = x; st.top++;} //入栈 char pop(stack &st){ st.top--; return st.SElemType[st.top];} //出栈 int main(){ stack s; initial(s); string str; getline(cin, str); char ch[150]; strcpy(ch,str.c_str()); int flag=1; int i; for(i=0; ch[i]!='\0'; i++){ //元素若为左则入栈 if((ch[i] == '{ ' )|| (ch[i] =='[') || (ch[i] =='(')){ push(s, ch[i]); }//元素若为右则出栈 赋值给a else if((ch[i] == '}') || (ch[i] ==']') || (ch[i] ==')')){ char a; a = pop(s); //若a与ch[i]匹配,下一个字符扫描 if((a == '{ ' && ch[i] == '}') || (a == '(' && ch[i] == ')') || (a == '[' && ch[i] == ']')){ continue; }else flag = 0; } } if(s.top!=0) flag=0; //判断无右符号匹配的情况 if(flag == 0){ cout<<"no"; }else cout<<"yes"; return 0;}
对栈的操作和使用还是不那么熟练,还是要好好练习。
第二个还是比较简单且易实现的,不过感觉自己的代码可能复杂了一点,很多地方都可以继续优化。
2.设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
#includeusing namespace std;#define MaxQsize 1001#define OK 1#define ERROR -1typedef int QElemType;typedef int status;typedef struct{ QElemType *base; //基地址 int front; //头指针 int rear; //尾指针 }sqQueue;status InitQueue(sqQueue &Q){ Q.base=new QElemType[MaxQsize]; //分配数组空间 Q.front=Q.rear=0; return OK; //队列为空} //构造队列 status EnQueue(sqQueue &Q,QElemType e){ if((Q.rear+1)%MaxQsize==Q.front) return ERROR; Q.base[Q.rear]=e; Q.rear=(Q.rear+1)%MaxQsize; return OK;} //入队 status DeQueue(sqQueue &Q,QElemType &e){ if(Q.front==Q.rear) return ERROR; e=Q.base[Q.front]; Q.front=(Q.front+1)%MaxQsize; return OK;} //出队 int GetHead(sqQueue Q){ if(Q.front!=Q.rear) return Q.base[Q.front];} //取队头元素 bool EmptyQueue(sqQueue Q){ if(Q.rear+1%MaxQsize==Q.front) return 1; else return 0;}void Push(int *arr,int n){ cout< >num; int result[num]; //总数字 for(int i=0;i >a; if(a%2!=0){ EnQueue(Queue1,a); } //奇数存入队列1 else if(a%2==0) EnQueue(Queue2,a); //偶数存入队列2 }while((Queue1.front!=Queue1.rear)&&(Queue2.front!=Queue2.rear)) { DeQueue(Queue1,tmp); result[i++]=tmp; DeQueue(Queue1,tmp); result[i++]=tmp; DeQueue(Queue2,tmp); result[i++]=tmp; } while(Queue1.front!=Queue1.rear) { DeQueue(Queue1,tmp); result[i++]=tmp; } while(Queue2.front!=Queue2.rear) { DeQueue(Queue2,tmp); result[i++]=tmp; } Push(result,num); return 0;}
实质就是把奇偶分到两个队列中,然后按照奇数输出;两个偶数输出一个的方式输出,最后一个队列空了之后再把剩下的全部输出。
值得一提的是以前一直都感觉诸如typedef int status这样的东西都是多此一举,结果当找Bug找到神经迷糊的时候怀疑到了这上面来,上网一搜才发现还是增强程序的可读性,让别人让自己都好看懂你这个函数是干什么的。
另外自学了一下sql中的queue,以后就不用这么麻烦啦,这是一篇参考博客:https://blog.csdn.net/cindywry/article/details/51919282。
最近事情有点多,可预见的以后事情会更多。但课内的学习不能落下。希望第四章能把一些东西琢磨透,把思维给提升上来。