博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Prefixes and Suffixes
阅读量:4321 次
发布时间:2019-06-06

本文共 1531 字,大约阅读时间需要 5 分钟。

题面

题目描述

给你一个字符串s,对于s的每一个前缀,如果它也是s的一个后缀,输出这个前缀在s中出现了多少次。

输入格式

一个字符串s(长度<=100000);只含有大写字母。

输出格式

第一行输出一个整数k——满足条件的前缀个数;

接下来k行,每行两个整数l,c,代表长度为l的前缀满足条件,在整个字符串中出现了c次。按l从小到大输出。

样例

Input1

ABACABA

Output1

31 43 27 1

Input2

AAA

Output2

31 32 23 1

题解

考虑每一个前缀\(str[0 .. i]\), 假如它也是字符串的后缀的话, 则有\(str[len - i - 1 .. len - 1] = str[0 .. i]\), 即\(match[len - i - 1] = i\).

对于每一个\(i\)判断是否存在\(match[len - i - 1] = i\)即可, 并统计整个\(match[]\)数组中\(match[n] >= i\)的数量即可.

#include 
#include
#include
const int L = (int)1e5; int main(){ static char str[L]; scanf("%s", str); int len = strlen(str); static int mch[L]; mch[0] = len - 1, mch[1] = -1; for(; mch[1] + 1 < len && str[mch[1] + 1] == str[1 + mch[1] + 1]; ++ mch[1]); int p = 1, mx = p + mch[p]; for(int i = 2; i < len; ++ i) { mch[i] = std::max(std::min(mx - i, mch[i - p]), -1); for(; i + mch[i] < len && str[mch[i] + 1] == str[i + mch[i] + 1]; ++ mch[i]); if(i + mch[i] > mx) p = i, mx = i + mch[i]; } static int sum[L]; memset(sum, 0, sizeof(sum)); for(int i = 0; i < len; ++ i) if(~ mch[i]) ++ sum[mch[i]]; for(int i = len - 1; i; -- i) sum[i - 1] += sum[i]; int cnt = 0; for(int i = 0; i < len; ++ i) if(mch[len - i - 1] == i) ++ cnt; printf("%d\n", cnt); for(int i = 0; i < len; ++ i) if(mch[len - i - 1] == i) printf("%d %d\n", i + 1, sum[i]);}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/7124636.html

你可能感兴趣的文章
晨会的重要性
查看>>
poj 3735 大数量反复操作问题(矩阵高速幂)
查看>>
自定义扩展Compare比较方法
查看>>
Swift 中的函数
查看>>
IOS开发关于测试的好的网址资源
查看>>
ArcGIS影像配准与空间配准
查看>>
考研日记第一篇
查看>>
个人简介
查看>>
Lucky Conversion(找规律)
查看>>
自定义一个处理图片的HttpHandler
查看>>
2、函数及常用模块
查看>>
Oracle按周统计数据的几种方法
查看>>
FileStream随机文件访问(访问文件中间某点的数据)
查看>>
bootstrap table单元格样式,行样式以及分页显示全部的设置
查看>>
洛谷P1106 删数问题
查看>>
数据库的自增字段代码生成器——解决不同数据库自增字段的差异机制
查看>>
从哲学角度分析“唯有真正了解一个人,才能真的做到爱他”
查看>>
【LeetCode】抽样 sampling(共4题)
查看>>
js清空页面控件值
查看>>
02-linux-换源-ui方式
查看>>