判断一个给定的字符串通过循环移位是否可以包含另一个字符串

比如说给定字符串“ABCD"通过循环移位是否可以包含“CDAB”。

有两种方法,一种方法就是通过创建另外一个字符串,这个字符串是两个“ABCD”的连接,然后应用kmp在新创建的字符串中查找"CDAB",这样的时间复杂度是O(n), 空间复杂度也是O(n),还有另外一种方法是可在O(n)时间内完成,下面给出代码:

#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;

void getNext(char* pattern, int length, int* next) {
	int i = 0;
	int j = -1;
	next[i] = -1;
	while (i < length - 1) {
		if (-1 == j || pattern[j] == pattern[i]) {
			++i;
			++j;
			if (pattern[i] == pattern[j]) {
				next[i] = next[j];
			} else {
				next[i] = j;
			}
		} else {
			j = next[j];
		}
	}
}

char* kmpSearch(char* source, char* pattern) {
	int src_len = strlen(source);
	int pat_len = strlen(pattern);
	int i, j;
	int* next = new int[pat_len];
	for (i = 0; i < pat_len; i++)
		next[i] = 0;
	getNext(pattern, pat_len, next);
	j = -1;
	i = 0;
	while (i < src_len && j < pat_len) {
		if (-1 == j || source[i] == pattern[j]) {
			++i;
			++j;
		} else {
			j = next[j];
		}
	}
	delete []next;
	if (j >= pat_len)
		return source + i - pat_len;
	return NULL;
}

bool isContainReverse(char* src, char* dst) {
	int src_len = strlen(src);
	int dst_len = strlen(dst);
	if (dst_len > src_len)
		return false;
	char* temp = new char[src_len * 2 + 1];
	sprintf(temp, "%s%s", src, src);
	bool rst = kmpSearch(temp, dst);
	delete []temp;
	return rst;
}

bool isReverseContain(char* src, char* dst) {
	int dst_contain_count = 0;
	int src_contain_count = 0;
	int src_len = strlen(src);
	int dst_len = strlen(dst);
	char ch = *dst;
	char* p = dst;
	while (*p) {
		if (ch != *p)
			break;
		dst_contain_count++;
		p++;
	}
	p = strchr(src, ch);
	while (p) {
		char* temp = p;
		src_contain_count = 0;
		while (*p) {
			if (ch != *p)
				break;
			src_contain_count++;
			p++;
		}
		p = strchr(p, ch);
		if (src_contain_count < dst_contain_count)
			continue;
		int i = temp - src + src_contain_count - dst_contain_count;
		int j = 0;
		while (j < dst_len) {
			if (src[i] != dst[j]) {
				break;
			}
			i = (i + 1) % src_len;
			j += 1;
		}
		if (j >= dst_len)
			return true;
	}
	return false;
}

int main(int argc, char* argv[]) {
	char src[] = "passportpasssportsssssport";
	char dst[] = "sssssportpassportpasssport";
	bool rst = isReverseContain(src, dst);
	if (rst)
		cout << "yes" << endl;
	else
		cout << "non" << endl;
	cin.get();
	return 0;
}


原文地址:https://www.cnblogs.com/dyllove98/p/3134648.html