牛客競賽——子串(KMP)

題目鏈接:https://ac.nowcoder.com/acm/problem/13253

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
string s, t;
int next_s[100010];
int num[1000010];
//得到1~n的k進製表示
void get_s(int n, int k) {
	int temp[20];
	int id_s = 0;
   //先轉數字
	for (int i = 1; i <= n; i++) {
		int id = 0;
		int kk = i;
		while (kk) {
			temp[id++] = kk % k;
			kk /= k;
		}
      //逆置
		for (int j = 0, k = id - 1; j < k; j++, k--) {
			swap(temp[j], temp[k]);
		}
		for (int j = 0; j < id; j++) {
			num[id_s++] = temp[j];
		}
	}
	s = "";
	char c;
   //數字轉字符串
	for (int i = 0; i < id_s;i++) {
		if (num[i] >= 10) {
			c = 'A' + (num[i] - 10);
		}
		else c = '0' + num[i];
		s.push_back(c);
	}
}
//求失配函數
void getnext() {
	memset(next_s, 0, sizeof(next_s));
	int j = -1, i = 0;
	next_s[0] = -1;
	int len = t.length();
	while (i < len) {
		if (j == -1 || t[i] == t[j])next_s[++i] = ++j;
		else j = next_s[j];
	}
}
//KMP模式匹配
bool KMP() {
	int j = 0;
	ll len = t.length();
	ll lens = s.length();
  // cout<<"s="<<s<<endl;
	for (int i = 0; i < lens;) {
		if (j == -1 || t[j] == s[i]) {
			i++; j++;
			if (j == len)return true;//找到
		}
		else j = next_s[j];
	}
	return false;
}
int main()
{
	IOS;
	int n;
	cin >> n;
	//getchar();
	cin >> t;
   getnext();
	bool flag = false;
	for (int k = 2; k <= 16; k++) {
		get_s(n, k);
		flag = KMP();
      //s.find(t)在字符串中子串t的位置
      //if(s.find(t)!=-1)flag=true;//也可以用此句,不需要getnext()和KMP()函數
		if (flag)break;
	}
	if (flag)cout << "yes" << endl;
	else cout << "no" << endl;
	getchar();
	getchar();
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章