1005. Programming Pattern (35)
来源:互联网 发布:网络联机小精灵 编辑:程序博客网 时间:2024/05/24 03:28
太菜了,这道题提交了30次,
用后缀数组做,开始用KMP做有一个测试点过不去,
然后学习后缀数组,这是学结构以来学到最崩溃的一次,好多细节没写好,然后错错错
先KMP的做法,就一个节点未过
#include<iostream>#include<string>using namespace std;int vv[1048577];int *nextval = (int *)malloc(sizeof(int)* 1048576);void getnext(string &s,int N) { int i = 0, j = -1; while (i < N) { if (j == -1 || s[i] == s[j]) { /*++i; ++j; if (s[i] == s[j]) nextval[i] = nextval[j]; else nextval[i] = j;*/ nextval[++i] = ++j; } else j = nextval[j]; } for (i = 1; i < N - 1; ++i) if (s[i] == s[nextval[i]]) nextval[i] = nextval[nextval[i]];}int main(){ int N; cin >> N; nextval[0] = -1; getchar(); string all; getline(cin, all); string str1; int M = 0, M_N = 0; for (int i = 0; i + N - 1 < all.size();++i) { if (all.size() - (i + N - 1) < M) break; if (vv[i]) continue; int num = 1; str1.assign(all, i, N); getnext(str1, N); int pos = i + 1; int j = 0; while (pos<all.size()) { if (j == -1 || all[pos] == str1[j]) { ++j; ++pos; } else j = nextval[j]; if (j == N) {vv[pos - N] = 1; j = nextval[j - 1]; pos--; ++num; } } //cout << str1 << " " << num << endl; if (num > M||(num==M && all[i]<all[M_N])) { M = num; M_N = i; } } cout << string(all, M_N, N) << " " << M << endl;}
再后缀数组的
#include<iostream>#include<string>#define MM 1100000using namespace std;char A[MM];//保存字符串1...n//rak[i]代表第i位置的等级,最后也可表示第i位置的排名;second[i],按第二关键字排序,第i名的位置,也暂存上一个过程的rak;//同一等级有相同的权,高等级权大,height[i],表示排名i的串和排名i-1的串最大前缀的字符数sa[i]第i名的位置;vis基排所用的临时数组int rak[MM], second[MM], sa[MM], vis[MM], height[MM];int m, n, w, k;//m代表等级的阶数,n代表串的长度,w代表当前字串长度,k求height所用int N;//输入数据,最终比较串的长度string s;//输入数据,串void initA()//初始化得到数组A,w,m,n,并初始化rak和second{ w = 1; m = 127; n = s.size(); for (int i = 1; i <= n; ++i) { rak[i] = A[i] = s[i - 1]; second[i] = i; }}void getsecond(){ int p = 0; //通过sa获得second for (int i = (n - w + 1) < 1 ? 1 : n - w + 1; i <= n; ++i) second[++p] = i;//****注意越界*********** for (int i = 1; i <= n; ++i) if (sa[i] > w) second[++p] = sa[i] - w;}void getsa()//基排{ //通过第一关键字排名rak,第二关键字排名second,基排得到sa for (int i = 1; i <= m; ++i) vis[i] = 0;//初始化 for (int i = 1; i <= n; ++i) ++vis[rak[second[i]]];//把所有数据的等级统一放到vis数组中 //求得sa for (int i = 2; i <= m; ++i) vis[i] += vis[i - 1]; for (int i = n; i >0; --i) sa[vis[rak[second[i]]]--] = second[i];//**********从n...1**************}bool com(int x, int y) { return second[x] == second[y] && second[x + w] == second[y + w]; }//比较排名相邻的串是否相同void getrak(int flag){ swap(rak, second);//为求新的rak,second暂存上一轮rak数据 int p = 1; rak[sa[1]] = p; if (flag) {//得到等级制的rak for (int i = 2; i <= n; ++i) rak[sa[i]] = com(sa[i], sa[i - 1]) ? p : ++p; } else {//得到排名制的rak for (int i = 2; i <= n; ++i) rak[sa[i]] = i; } m = p;}void getheight() { //for (int i = 1; i <= n; ++i) cout << string(s, sa[i] - 1, n - sa[i]+1) << endl; k = 0; for (int i = 1; i <= n; height[rak[i++]] = k) { if (k) --k; for (int j = sa[rak[i] - 1]; A[i + k] == A[j + k];) { if (++k >= N) { k = N; break; } } }}int main(){ cin >> N; getchar(); getline(cin, s); initA(); getsa(); while (1) { getsecond(); getsa(); getrak(1); if (w >= N) break; w += w; } getrak(0); getheight(); //求结果 int g = 1, h = sa[1];//过程数据,临时存放相同串个数和其某个串的第一字符位置 int re_g = 1, _h = 1;//存放结果 for (int i = 2; i <= n; ++i) { if (height[i] >= N) { ++g; } else { if (g > re_g || (g == re_g && s[h - 1] < s[_h - 1])) { re_g = g; _h = h; } g = 1; h = sa[i]; } } if (g > re_g || (g == re_g && s[h - 1] < s[_h - 1])) {//最后的比较 re_g = g; _h = h; } cout << string(s, _h - 1, N) << " " << re_g << endl;}
阅读全文
0 0
- 1005. Programming Pattern (35)
- 1005. Programming Pattern (35)【待解决】
- 1005. Programming Pattern (35)解题报告
- pat-top 1005. Programming Pattern (35)
- PAT (Top Level) Practise 1005Programming Pattern (35)
- Programming Assignment 3: Pattern Recognition
- Quartz 2D Programming Guide -Pattern
- Concurrent Programming in Java(TM): Design Principles and Pattern
- Prototype-oriented Programming和Prototype Pattern 的区别与联系
- pattern
- pattern
- Pattern
- Pattern
- Pattern
- Pattern
- Pattern
- Active Object -An Object Behavioral Pattern for Concurrent Programming 主动对象模式 (转)
- programming
- 判断一个栈的弹出序列是否为合法序列
- bootstrap3框架
- Android_生命周期
- sql之left join、right join、inner join的区别
- 详解linux运维工程师入门级必备技能
- 1005. Programming Pattern (35)
- PHP day8 TP5 model更新,软删除
- 高质量JAVA社区
- android studio上的jni编译流程以及Android.mk文件的处理
- 理解 Angular 中的 $digest() 和 $apply()
- select传值到后台的问题
- bzoj 3545: [ONTAK2010]Peaks 线段树合并
- [leetcode]417. Pacific Atlantic Water Flow
- FeignClient 在 oauth2 中与 hystrix 线程策略冲突问题造成的权限问题