DS 串 KMP算法+子串循环问题

一  KMP算法

主串和模式串下标都是从0开始

1. 获得next数组的值

void get_next(string t) {
	int j = 0, k = -1;
	next_[0] = -1;
	while (j < t.size() - 1) {
		if (k == -1 || t[j] == t[k]) {
			k++, j++;
			next_[j] = k;
		} else
			k = next_[k];
	}
}

2.kmp匹配过程

特别注意:由于size()是无符号整型,而j为整形,j有可能为负数,他们比较大小的时候很有可能出问题,因此需要t.size()强制转换为int类型

int KMP(string s, string t) {
	int i = 0, j = 0;
	while (i < s.size() && j < (int)t.size()) {
		if (j == -1 || s[i] == t[j])
			i++, j++;
		else
			j = next_[j];
	}
	if (j == t.size())
		return i - j;
	return -1;
}

二、例题——子串循环问题 

先了解几个概念:循环节:(参考循环小数),可以理解为 使这个子串变成“循环小数”

1.最小循环节:len-next[len]

2.若这个字符串可以完全由循环节构成,则有:len%(len-next[len])==0

OJ(id:73)

题目描述:

给定一个字符串,求需要添加至少几个字符到字符串末尾才能使得整个字符串串由某一个不为本身的子串循环构成?
如"abca",添加"bc"后构成"abcabc",其由子串"abc"循环构成;也可以添加"abca"后构成"abcaabca",其由子串"abca"循环构成,相比之下"bc"只有2个字符,添加的字符量最少。

输入:

第一行包括一个整数T(1 <= T <= 100),代表测试组数

每组测试数据包括一行字符串,其长度范围为 [3, 10^4]

 输出:

对于每组测试数据

输出一个整数N,代表添加的最小字符数量

#include
using namespace std;
int next_[100];
void get_next(string t) {
	int j = 0, k = -1;
	next_[0] = -1;
	while (j < t.size() - 1) {
		if (k == -1 || t[j] == t[k]) {
			k++, j++;
			next_[j] = k;
		} else
			k = next_[k];
	}
}
int main() {
	int T;
	string s;
	cin >> T;
	while(T--) {
		cin >> s;
		int len = s.size();
		s += '#';
		get_next(s);
		if(len%(len-next_[len])==0) {
			if(next_[len]==0) cout << len << endl; 
			else cout << 0 << endl; 
		}
		else cout << len-next_[len]-(len%(len-next_[len])) << endl; 
                    //循环节的长度-已有的不完全的字符的长度=需要补充的长度
	}
	return 0;
}

被老师逼着写了好多遍理论,突然代码也悟了o(╥﹏╥)o 

你可能感兴趣的:(数据结构,算法,c++,数据结构)