#include<bits/stdc++.h> using namespace std; typedef long long ll; const int base=131; const int maxn=1e6+100; ll p[maxn],hush[maxn],len; string s; void init() { p[1]=base; for(int i=2;i<=maxn;i++) { p[i]=p[i-1]*base; } } void hsh() { for(int i=1;i<=len;i++) { hush[i]=hush[i-1]*base+s[i-1]; } } int hslr(int l,int r) { return hush[r]-hush[l]*p[r-l]; } bool check(ll hh,int k) { for(int i=1+k;i<=len-k;i+=k) { if(hslr(i,i+k-1)!=hh) { return false; } } return true; } int main() { while(cin>>s) { if(s[0]=='.') break; len=s.size(); // cout<<len<<endl; hsh(); for(int i=1;i<=len;i++) { if(len%i==0) { if(check(hush[i],i)) { cout<<len/i<<endl; break; } } } } return 0; }哪里不对?
时间: 2025-04-04 22:05:26 浏览: 34
这个程序的主要功能是对输入字符串进行哈希操作,并检查该字符串是否由某个最短的重复子串组成。如果有问题,则会输出相应结果。下面我们逐步分析代码并找出可能存在的错误点:
---
### **已知信息**
1. 程序的功能目标是检测给定字符串是否可以拆分为若干个相同的连续子串。
2. 主要涉及以下部分:
- 哈希初始化函数 (`init`) 和计算函数 (`hsh`)
- 子串哈希值提取函数 (`hslr`)
- 检查是否存在满足条件的周期性模式函数 (`check`)
#### 具体步骤:
1. 初始化幂次数组 `p[]`,表示从第 0 到第 n-1 位置字符对应的权值。
2. 计算整个字符串前缀哈希值存入 `hush[]` 数组。
3. 循环尝试所有可能的子串长度 `i`(要求能够整除总长度 `len`),并通过验证函数 `check()` 测试每个可能性。
---
### **潜在问题及修复建议**
#### **问题一:变量越界风险**
在 `hsh()` 函数中有如下循环语句:
```cpp
for(int i=1;i<=len;i++) {
hush[i] = hush[i-1]*base + s[i-1];
}
```
这里可能存在精度溢出的风险。由于每次乘法运算都会使得哈希值迅速增大,在较长字符串的情况下可能会超出 `long long` 的范围导致错误结果。
**解决办法**:引入模数取余操作限制最大值大小,同时保证不影响最终匹配判断的一致性。例如可以在每一项加法后添加 `% MOD` 这样的运算符号(其中 MOD 设定足够大的素数值如 $10^9+7$ 或其他常用选项)。
修改后的片段:
```cpp
const ll MOD = 1e9+7;
// 修改 init() 内部逻辑同样加入 mod 操作
void init(){
p[1]=base%MOD;
for(int i=2;i<=maxn;i++){
p[i]=(p[i-1]*base)%MOD;
}
}
void hsh(){
for(int i=1;i<=len;i++){
hush[i] = (hush[i-1]*base + s[i-1]) % MOD;
}
}
int hslr(int l, int r){
return ((hush[r]-hush[l]*p[r-l]%MOD)+MOD) % MOD; // 防止负数情况下的正确处理
}
```
#### **问题二:边界条件未充分考虑**
当进入主循环时,
```cpp
if(s[0]=='.') break;
```
仅针对单独一行首字母为 '.' 就停止读取新行内容的行为进行了特别说明。然而对于非终止情形下继续处理的数据却没有任何额外保护措施;此外也没有确认实际输入是否完全合法合规等问题存在。
**改进方向**: 加强异常捕获机制以及数据校验过程保障整体鲁棒性更强一些。比如增加 try-catch 结构包裹关键区域或者预先设定默认空值避免非法访问等隐患发生。
#### **问题三:效率优化空间较大**
目前算法复杂度大致为 O(n√n),因为需要遍历所有可行因子作为候选分割宽度,并逐一检验符合条件的部分再退出搜索路径即可完成任务。但对于极端测试样例而言性能表现未必理想。
进一步提高速度的话可以思考快速傅立叶变换(FFT)-based substring matching techniques 或者其他的高级技巧减少不必要的冗长比较开销达到接近线性的理论极限效果。
---
### **总结修正版完整代码框架参考实例:**
以下是综合上述改进建议之后重构得到的新版本伪代码描述:
```c++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9+7;
const int BASE = 131;
const int MAXN = 1e6+100;
ll pow_arr[MAXN], hash_val[MAXN];
inline void precompute_hashes(const string& str) {
int length=str.size();
pow_arr[0] = 1;
for (size_t i = 1; i <=length ; ++i) {
pow_arr[i]=(pow_arr[i-1]*BASE)%MOD;
hash_val[i] =(hash_val[i-1]*BASE+(str[i-1]-'a'+1))%MOD ;
}
}
ll get_range_hash_value(int left_pos , int right_pos ){
ll res=(hash_val[right_pos ]-(hash_val[left_pos-1]*pow_arr[right_pos-left_pos+1])%MOD);
if(res<0 )res +=MOD;
return res;
}
bool verify_repetition_pattern(string &text,ll candidate_sub_len){
set<ll> unique_hvs;
for(size_t start_idx=0 ;start_idx+candiate_sub_len<= text.length();start_idx+=candidate_sub_len ){
unique_hvs.insert(get_range_hash_value(start_idx+1,start_idx+candidate_sub_len ));
if(unique_hvs.size()>1 )return false;
}
return true &&unique_hvs.size()==1 ;
}
int main(){
ios::sync_with_stdio(false); cin.tie(NULL);
string input_line;
while(true ){
cin >>input_line ;
if(input_line .front ()=='.' )
break ;
precompute_hashes(input_line );
for(auto potential_periodicity : divisors_of(input_line.length())){
if(verify_repetition_pattern(input_line,potential_periodicity)){
cout <<potential_periodicity<< "\n" ;
goto NEXT_INPUT;// Early termination once found valid answer.
}
}
NEXT_INPUT:;
}
return EXIT_SUCCESS;
}
```
---
阅读全文
相关推荐













