最短循環フェスティバル(KMP)の実現

文字列strの長さがlenであるとすると、strには最小ループセクションがあります。ループセクションの長さcycleLenはlen-next [len]であり、ループ部分文字列はstr [0 ... len-next [len]です。 -1]

  1. lenがlen-next [len]で割り切れる場合、文字列strは完全にループで構成できることを意味します。
  2. そうでない場合は、完了するためにさらにいくつかの文字を追加する必要があり、その数を補足する必要があることを意味しますcycleLen-len%cycleLen、補足される文字列はstr [len%cycleLen ... cycleLen-len%cycleLen ]
#include <iostream>
#include <vector>
using namespace std;

/* str 数组的 str.length() + 1 个next数组值 */
void getNext(string& str, vector<int>& next) {
    
    
	next.at(1) = 0;
	if (str.length() == 1) {
    
    
		return;
	}
	for (int i = 2, cn = 0; i <= str.length(); i++) {
    
    
		if (str.at(i - 1) == str.at(cn)) {
    
    
			next.at(i) = ++cn;
		}
		else if (cn == 0) {
    
    
			next.at(i) = 0;
		}
		else {
    
    
			cn = next.at(cn);
		}
	}
}

int main() {
    
    
	string str("0123012301");
	int len = str.length();
	vector<int> next(len + 1, -1);
	getNext(str, next);

	/* 循环节长度 */
	int cycleLen = len - next.at(len);
	cout << "最短循环节长度: " << cycleLen << endl;

	/* 字符串长度对循环节长度取余是0,则为循环字符串,否则需要补充字符  */
	if (len % cycleLen == 0) {
    
    
		cout << "最短循环节是: ";
		cout << str.substr(0, cycleLen).c_str() << endl;
	}
	else {
    
    
		cout << "需要补充的字符: ";
		/* 需要补充的长度为cycleLen - (next.at(len) % cycleLen) */
		cout << str.substr(next.at(len) % cycleLen, cycleLen - (next.at(len) % cycleLen)).c_str() << endl;
	}

	system("pause");
	return 0;
}

侵害がある場合は、連絡して削除してください。エラーがある場合は、訂正してください。ありがとうございます。

おすすめ

転載: blog.csdn.net/xiao_ma_nong_last/article/details/105630994