DAY10
学习了王道-数据结构考研-KMP部分+ACWING算法基础课KMP模板。接下来补DAY9的任务、完成DAY10习题。
(卡码网)替换数字,数组填充问题
新的双指针法:针对数组填充
自己写一遍看能不能过:又学到了:cout<<s<<endl;可以直接打印出string s;
- #include<iostream>
- using namespace std;
- int main()
- {
- string s;
- cin>>s;
- int lo=s.size(),count=0;
- for(int i=0;i<lo;i++)
- if(s[i]<='9'&&s[i]>='0') count++;
- int ln=lo+count*5;
- s.resize(ln);
- for(int i=lo-1,j=ln-1;i<j;i--,j--)
- {
- if(s[i]>'9'||s[i]<'0') s[j]=s[i];
- else{
- s[j]='r';
- s[j-1]='e';
- s[j-2]='b';
- s[j-3]='m';
- s[j-4]='u';
- s[j-5]='n';
- j-=5;
- }
- }
- cout<<s<<endl;
- return 0;
- }
232用栈实现队列
Stack是栈 stack<int>
Queue是队列 queue<int>
在ACWING语法基础课上学过,回顾一下:
代码随想录的,并没有把in栈固定起来(不复原),动态地,就比较难理解。这里使用acwing的。易懂简单可靠!
- class MyQueue {
- public:
- stack<int> s1,s2;
- MyQueue() {
- }
- void push(int x) {
- s1.push(x);
- }
- int pop() {
- while(s1.size()>1) s2.push(s1.top()),s1.pop();
- int t=s1.top();
- s1.pop();
- while(s2.size()>0) s1.push(s2.top()),s2.pop();
- return t;
- }
- int peek() {
- while(s1.size()>1) s2.push(s1.top()),s1.pop();
- int t=s1.top();
- while(s2.size()>0) s1.push(s2.top()),s2.pop();
- return t;
- }
- bool empty() {
- return s1.empty();
- }
- };
- /**
- * Your MyQueue object will be instantiated and called as such:
- * MyQueue* obj = new MyQueue();
- * obj->push(x);
- * int param_2 = obj->pop();
- * int param_3 = obj->peek();
- * bool param_4 = obj->empty();
- */
225用队列实现栈
队列头部元素是front,队列没有pop
- class MyStack {
- public:
- queue<int> p1,p2;
- MyStack() {
- }
- void push(int x) {
- p1.push(x);
- }
- int pop() {
- while(p1.size()>1) p2.push(p1.front()),p1.pop();
- int res=p1.front();
- p1.pop();
- p1=p2;
- while(!p2.empty()) p2.pop();
- return res;
- }
- int top() {
- return p1.back();
- }
- bool empty() {
- return p1.empty();
- }
- };
- /**
- * Your MyStack object will be instantiated and called as such:
- * MyStack* obj = new MyStack();
- * obj->push(x);
- * int param_2 = obj->pop();
- * int param_3 = obj->top();
- * bool param_4 = obj->empty();
- */
总结:
题目中允许使用的:
Stack:竖着放,top(),pop()
Queue:横着放,有back(),front(),pop()
他们都有push(),empty(),size(),
ACWING831KMP字符串
Next数组:最大后缀和前缀相等
- #include<iostream>
- using namespace std;
- const int N=10010,M=100010;
- int n,m;
- char p[N],s[M];
- //不要写next[N],因为有可能报错,写ne。
- int ne[N];
- int main()
- {
- //让下标从1开始
- cin>>n>>p+1>>m>>s+1;
- //求next数组:next[1]=0 第一个字母失败了,就只能从0开始。
- //从最长匹配前后缀来理解,就好写算法模版了.即:p[1,i]=p[i-1+1,j];
- 因为next[1]=0,那么i=2开始
- for(int i=2,j=0;i<=n;i++)
- {
- while(j&&p[i]!=p[j+1]) j=ne[j];
- //这时候是自己和自己做KMP匹配,j+1是因为:分界线之后才开始真正匹配.
- if(p[i]==p[j+1]) j++;
- ne[i]=j;//求得是next[i]
- }
- //KMP匹配过程
- //记住:当前与s[i]匹配的应当是p[j+1]。即:j总是往前错一位。
- for(int i=0,j=0;i<=m;i++)
- {/*j不在0位,且两者匹配不上。持续相同情况用while:
- 一直退直到退无可退(j==0),也可能是已经匹配上了。那么之后用if来判断是两种情况中的哪一种
- */
- while(j&&s[i]!=s[j+1]) j=ne[j];
- if(s[i]==p[j+1]) j++;
- //匹配成功
- if(j==n)
- {
- //返回出现的起始位置记得+1;画个图就好模拟了
- printf("%d ",i-n+1);
- //匹配好了,继续匹配的话,i不回溯,j=ne[j](不理解);
- //解释:把前面的匹配成功的信息利用起来的意思
- j=ne[j];//
- }
- }
- return 0;
- }
如果题目的下标(一般来说都是)是从0开始,那么printf(“%d “,i-n+1);改成printf(“%d “,i-n);即可。