Power Strings

news2025/1/17 4:00:51

Power Strings

题面翻译

题意简述:

求一个字符串由多少个重复的子串连接而成。

例如 ababab 由三个 ab 连接而成,abcdabcd 由一个 abcd 连接而成。

输入格式

本题多组数据

每一组数据仅有一行,这一行仅有一个字符串 s s s

输入的结束标志为一个 .

输出格式

对于每一组数据,输出这组字符串由多少个重复的子串连接而成。

说明/提示

1 ≤ ∣ s ∣ ≤ 1 0 6 1\le |s|\le 10^6 1s106

题目描述

PDF

输入格式

输出格式

样例 #1

样例输入 #1

abcd
aaaa
ababab
.

样例输出 #1

1
4
3

读题

采用hash做法,通过哈希值来判断字符串中是否存在重复子串,并求出重复子串的个数。

此题较优秀,笔者在此想分为两部分来谈论,具体分为总览分析,当然,在阅读后有兴趣的读者可以通过网络,查阅相关资料(比如蓝书–《算法竞赛入门经典·训练指南》)。

1.总览

根据题目,很容易想到:

  1. 读入一个字符串,存储在数组 aa 中,作为主串。
  2. 检查是否为结束标志,即字符串以句号 '.' 开头。如果是,则退出程序;否则继续执行后续步骤。
  3. 计算输入字符串 aa 的长度,存储在变量 n 中。
  4. 初始化哈希数组 h,数组大小设为 M
  5. 计算哈希数组 h,其中 h[i] 表示字符串 aa 的前缀子串 aa[1...i] 的哈希值。
  6. 进入循环遍历,枚举每个可能的重复模式长度 i
  7. 判断当前长度 i 是否能整除字符串长度 n,如果不能,则继续下一次循环。
  8. 计算模式串的哈希值 s,即子串 aa[1...i] 的哈希值。
  9. 调用 check 函数,检查字符串是否存在长度为 i 的重复模式。check 函数使用哈希值进行匹配判断。
  10. 如果存在重复模式,则输出重复模式的个数,即字符串长度除以重复模式长度。
  11. 回到第 5 步,继续处理下一个输入字符串。

代码

#include<bits/stdc++.h>
using namespace std;
const int x=1311,M=1e7;
int a[M],b[M],h[M],f=0;
char aa[M],bb[M];
int n,s;
bool init(){
	scanf("%s",aa+1);
	if(aa[1]=='.') return 0;
	n=strlen(aa+1);
	h[0]=0;
	for (int i=1;i<=n;i++) h[i]=h[i-1]*x+int(aa[i]-'A'+1);
	return 1;
}
bool check(int v,int k){
	for (int i=1;i<=n;i+=k) 
		if (v!=h[i+k-1]-h[i-1]*a[k]) return 0;
	return 1;
}
int main(){
	a[0]=1;
	for (int i=1;i<=1000000;i++) a[i]=a[i-1]*x;
	while (init()){
		for (int i=1;i<=n;++i){
			if (n%i) continue;
			if (i>n/2){cout<<1<<endl;break;}
			s=h[i];
			if (check(s,i)){
				cout<<n/i<<endl;
				break;
			}
		}
	}
	return 0;
}

2.分析

相信读者已经看完总览和代码了,接下来是分析,心急的读者可能想跳过了,但笔者十分希望认真看完,因为它实在是太优美,太巧妙了:

check

bool check(int v,int k){
	for (int i=1;i<=n;i+=k) 
		if (v!=h[i+k-1]-h[i-1]*a[k]) return 0;
	return 1;
}

函数 check 被用于判断字符串是否存在指定长度的重复子串。笔者喜欢封装函数。

  1. 通过循环遍历,以定长度等于 k 的方式检查是否存在hash值为v的重复子串。
  2. 检查当前位置子串的哈希值是否等于预先计算的目标哈希值 v。如果不相等,则说明不是重复子串,返回 false
  3. 如果循环结束后都没有找到不匹配的情况,则说明字符串一定存在长度为 k 的重复子串,返回 true

init

bool init(){
	scanf("%s",aa+1);
	if(aa[1]=='.') return 0;
	n=strlen(aa+1);
	h[0]=0;
	for (int i=1;i<=n;i++) h[i]=h[i-1]*x+int(aa[i]-'A'+1);
	return 1;
}

总览中有许多操作,很多都是初始化,我们可以使用do-while,但笔者认为不如使用函数封装下。
需要注意下hash值的递推计算公式,在上一题解中,已做阐述,笔者在此不过多赘述。

附加代码

#include <iostream>
#include <string>
using namespace std;

int countRepeatingSubstrings(string s) {
    int n = s.length();
    for (int i = 1; i <= n / 2; i++) {
        if (n % i == 0) {
            bool isRepeating = true;
            for (int j = i; j < n; j++) {
                if (s[j] != s[j % i]) {
                    isRepeating = false;
                    break;
                }
            }
            if (isRepeating) {
                return n / i;
            }
        }
    }
    return 1;
}

int main() {
    string s;
    cin >> s;
    while (s != ".") {
        int repeatingCount = countRepeatingSubstrings(s);
        cout << repeatingCount << endl;
        cin >> s;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/678409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nmap常用扫描命令

1. nmap扫描一台机器 nmap 192.168.133.672. nmap扫描一台机器,查看打开端口及详细信息 nmap -v 192.168.133.673. nmap 指定端口/端口范围扫描 nmap -p 1-65535 192.168.133.67nmap -p 1-100,135,8080,443 192.168.133.67 <

chatgpt赋能python:Python电脑上图标是什么样子?

Python电脑上图标是什么样子&#xff1f; 在计算机系统中&#xff0c;图标是一种可视化的元素&#xff0c;用于代表具体的应用程序或文件。Python是一种开源的高级编程语言&#xff0c;越来越多的人开始使用它进行软件开发和数据科学。在电脑上&#xff0c;Python的图标是怎样…

简单Web UI 自动化测试框架 seldom

pyse 更名为 seldom WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动化测试框架。 特点 提供更加简单API编写自动化测试。提供脚手架&#xff0c;快速生成自动化测试项目。自动生成HTML测试报告生成。自带断言方…

3.跑马灯

1.GPIO的输出模式&#xff1a; 推挽模式输出&#xff1a;因为LED0和LED1阳极都是3.3V&#xff0c;需要将阴极设置为低电平才可以点亮LED&#xff1b;操作io口时&#xff0c;必须引入源文件和头文件&#xff1b;关于时钟的文件存放在rcc中&#xff1b; 2.GPIO库函数介绍&#…

【传感器】一种鲁棒的imu比例系数与偏移的校准算法

简介 最近在学习传感器相关的知识&#xff0c;在国外的一篇论文学习过程中&#xff0c;觉得这篇论文的校准方法是个不错的参考。 这种校准简单且比较鲁棒的算法&#xff0c;操作简单&#xff0c;且除了偏移与比例系数&#xff0c;还可以估计出传感器 xyz 轴相对于标准正交三轴…

《Python自动化测试九章经》

Python是当前非常流行的一门编程语言&#xff0c;它除了在人工智能、数据处理、Web开发、网络爬虫等领域得到广泛使用之外&#xff0c;他也非常适合软件测试人员使用&#xff0c;但是&#xff0c;对于刚入行的测试小白来说&#xff0c;并不知道学习Python语言可以用来完成哪些测…

chatgpt赋能python:Python用于炒股

Python用于炒股 随着互联网和数据科学的发展&#xff0c;越来越多的投资者开始依靠计算机和数据科学来进行更高效的投资。Python是一种广泛使用的编程语言&#xff0c;可以帮助投资者更好地处理数据和自动化交易。本文将简要介绍Python如何用于炒股&#xff0c;并分享一些有用…

canvas详解02-样式和颜色控制

在绘制图形的章节里&#xff0c;我只用到默认的线条和填充样式。而在这一章里&#xff0c;我们将会探讨 canvas 全部的可选项&#xff0c;来绘制出更加吸引人的内容。 #色彩 Colors 到目前为止&#xff0c;我们只看到过绘制内容的方法。如果我们想要给图形上色&#xff0c;有两…

捕捉信号/信号的处理步骤

一、信号会在合适的时候被处理 先摆出一个结论&#xff1a;信号会在合适的时候被处理。 当然&#xff0c;这里说的信号默认排除了实时信号&#xff0c;那个是已接收到信号就立马处理信号。 上面说的合适的时候其实就是进程从内核态切换到用户态的时候。 二、何为内核态和用户…

Golang -> Golang 变量

Golang 变量 Golang 变量使用的三种方式变量的声明&#xff0c;初始化和赋值程序中 号的使用数据类型的基本介绍int 的无符号的类型&#xff1a;int 的其它类型的说明:整型的使用细节 小数类型/浮点型小数类型分类浮点型使用细节 字符类型字符类型使用细节字符类型本质探讨 布…

java面向对象部分

在学校时学的比较乱&#xff0c;趁暑假再系统的学一遍 访问权限控制 private&#xff1a;私有&#xff0c;只能被本身类访问 什么都不写&#xff1a;默认&#xff0c;只能被类本身和同包中的其他类访问 protected&#xff1a;受保护的&#xff0c;只能被类本身和同包中的其…

计算物理专题:实对称矩阵特征值的求解问题

我们需要求出一个实对称阵的全部特征值与特征向量实对称矩阵特征值的求解是计算量子力学的基础之一&#xff08;算符是厄米的&#xff09;同时&#xff0c;实对称矩阵的求解也是使用有限差分法解本征方程的重要方法之一 雅克比方法 我知道这个推导过程非常的复杂&#xff0c;所…

计算物理专题:双向打靶法解决本征值问题

计算物理专题&#xff1a;双向打靶法解决本征值问题 双向打靶法全部代码 EigenMethods.py import numpy as np import matplotlib.pyplot as plt from SchrodingerTools import *#type-ode1: ## y(x)f(x)y(x) g(x) ##tips: ##lambda eigen,x:f(eigen,x)def replace_eigen(ei…

365天深度学习训练营-第T3周:天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;TensorFlow入门实战&#xff5c;第3周&#xff1a;天气识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 语言环境&#xff1a…

Web网页制作-知识点(4)——CSS盒子模型、弹性盒模型(flex box)、文档流、浮动、清除浮动、定位、圆角、阴影

目录 CSS盒子模型 概念 弹性盒模型&#xff08;flex box&#xff09; 内容 父元素上的属性 display属性 flex-direction属性 justify-content属性 align-items属性 子元素上的属性 flex 文档流&#xff08;标准流&#xff09; 浮动 定义 浮动的原理 清除浮动 …

Java开发 - 负载均衡你了解多少?

前言 前面很多篇博客都有涉及到负载均衡&#xff0c;而负载均衡也并不是某一个框架的专利&#xff0c;从博主接触Java以来&#xff0c;使用的很多框架都自带了负载均衡的特点。今天&#xff0c;我们就来一探究竟&#xff0c;了解下负载均衡是什么&#xff0c;该怎么在项目中使…

Python 函数:理解并使用 return 语句

你好&#xff0c;我是悦创。 函数在 Python 编程中起着至关重要的作用。他们封装了一段代码&#xff0c;并给它一个名字&#xff0c;这样我们可以在程序的任何地方&#xff0c;通过这个名字来调用这段代码。return 是函数的一个重要组成部分&#xff0c;它可以使函数输出一个值…

差分方程转化为Z变换方程

差分方程是描述离散时间系统动态行为的数学工具&#xff0c;而Z变换则是将离散时间信号从时间域转换到复频域的工具。因此&#xff0c;将差分方程转换为Z变换方程可以方便我们在复频域分析离散时间系统的动态行为。 假设我们有一个差分方程: a n x [ n ] a n − 1 x [ n − 1…

rabbitmq第二课-RabbitMQ核心编程模型以及消息应用场景详解

一、回顾RabbitMQ基础概念 二、RabbitMQ基础编程模型 使用RabbitMQ提供的原生客户端API进行交互。这是使用RabbitMQ的基础。 1.1、maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version&g…

C语言:使用指针使字符串逆序

题目&#xff1a; 链接&#xff1a;字符逆序__牛客网 来源&#xff1a;牛客网 将一个字符串str的内容颠倒过来&#xff0c;并输出。 输入描述: 输入一个字符串&#xff0c;可以有空格 输出描述: 输出逆序的字符串 示例1 输入 I am a student 输出 tneduts a ma I …