UVA 475 - Wild Thing(KMP)

UVA 475 - Wild Thing

题目链接

题意:给定一个带通配符的文件名作为格式,后面跟一个文件名,要求输出符合格式的文件名

思路:先把带通配符的文件名根据星号位置进行分解,然后对于每个文件名去判断,判断的方法用KMP,如果格式的每段都能在文件名中不断往后一一匹配上,那么就是可以的,注意考虑开头和结尾没有星号的情况,还有这题就是如果找不到一个合适的,就什么都不输出,包括换行

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>
using namespace std;

const int N = 100005;

string s, name;
vector<string> g;
vector<string> ans;
int next[N], ll, rr;
bool have;

void getnext(string name) {
    next[0] = next[1] = 0;
    int j = 0;
    for (int i = 2; i <= name.length(); i++) {
	while (j && name[i - 1] != name[j]) j = next[j];
	if (name[i - 1] == name[j]) j++;
	next[i] = j;
    }
}

bool find(string name) {
    int u = ll, j = 0;
    if (u == rr) return true;
    for (int i = 0; i < name.length(); i++) {
	while (j && name[i] != g[u][j]) j = next[j];
	if (name[i] == g[u][j]) j++;
	if (j == g[u].length()) {
	    u++;
	    j = 0;
	    if (u == rr) return true;
	}
    }
    return false;
}

bool check() {
    if (!have) return name == g[0];
    int l = 0, r = name.length() - 1;
    if (s[s.length() - 1] != '*') {
	string last = g[g.size() - 1];
	for (int i = last.length() - 1; i >= 0; i--) {
	    if (name[r] != last[i]) return false;
	    r--;
	}
    }
    if (s[0] != '*') {
	string fir = g[0];
	for (int i = 0; i < fir.length(); i++) {
	    if (name[l] != fir[i]) return false;
	    l++;
	}
    }
    string tmp = "";
    for (int i = l; i <= r; i++)
	tmp += name[i];
    getnext(tmp);
    if (find(tmp)) return true;
    return false;
}

void init() {
    g.clear();
    string tmp = "";
    have = false;
    for (int i = 0; i < s.length(); i++) {
	if (s[i] == '*') {
	    have = true;
	    if (tmp != "")
		g.push_back(tmp);
	    tmp = "";
	    continue;
	}
	tmp += s[i];
    }
    if (tmp != "")
	g.push_back(tmp);
    ll = 0;
    rr = g.size();
    if (s[0] != '*') ll++;
    if (s[s.length() - 1] != '*') rr--;
}

int main() {
    int flag = 0;
    int bo = 0;
    while (getline(cin, s)) {
	init();
	flag = 0;
	ans.clear();
	while (getline(cin, name)) {
	    if (name == "") break;
	    if (check()) {
		flag = 1;
		ans.push_back(name);
	    }
	}
	if (flag) {
	    if (bo) printf("\n");
	    else bo = 1;
	    cout << "MATCHES FOR THE PATTERN: " << s << endl;
	    for (int i = 0; i < ans.size(); i++)
		cout << ans[i] << endl;
	}
    }
    return 0;
}

UVA 475 - Wild Thing(KMP)

时间: 2024-10-05 04:43:21

UVA 475 - Wild Thing(KMP)的相关文章

UVA - 10298 Power Strings (KMP求字符串循环节)

Description Problem D: Power Strings Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiati

UVA 10298 - Power Strings(KMP)

UVA 10298 - Power Strings 题目链接 题意:本意其实就是,给定一个字符串,求出最小循环节需要几次循环出原字符串 思路:利用KMP中next数组的性质,n - next[n]就是最小循环节,然后n / 循环节就是答案 代码: #include <cstdio> #include <cstring> const int N = 1000005; char str[N]; int next[N]; void getnext() { int n = strlen(s

uva 11557 - Code Theft(KMP)

题目链接:uva 11557 - Code Theft 题目大意:给定n个文本,每个文本有一个文本名,现在给出一个文本,求给定文本和n个文本中连续相同行数最大值,并且输出文本名,注意为0时不用输出其它的文本名. 解题思路:将每个字符串用映射成一个hash值,然后对匹配文本枚举后缀,建立失配数组进行KMP匹配,记录下每个文本的匹配最大值. #include <cstdio> #include <cstring> #include <map> #include <st

UVA 11557 - Code Theft (KMP + HASH)

UVA 11557 - Code Theft 题目链接 题意:给定一些代码文本,然后在给定一个现有文本,找出这个现有文本和前面代码文本,重复连续行最多的这些文本 思路:把每一行hash成一个值,然后对于每一个文本计算最大匹配值,枚举后缀,然后利用KMP去找即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <string> #include <iostream&g

UVA 11475 后缀数组/KMP

题目链接: 题意:给定一个只含字母的字符串,求在字符串末尾添加尽量少的字符使得字符串为回文串. 思路:因为只能从末尾添加字符,所以其实求的是最长的后缀回文串.那么添加的字符为除了这个原串的最长后缀回文串之外的其他字符.于是问题就转变成了求字符串的最长后缀回文串,对于后缀数组求回文串子串的做法,将整个字符串反过来写在原字符串后面,中间用一个特殊的字符隔开.这样就把问题变为了求这个新的字符串的某两个后缀的最长公共前缀.奇数长度和偶数长度的分开做.对于求奇数长度,假设现在枚举的位置为i,那么对应在反过

UVA 12467 - Secret Word

UVA 12467 - Secret Word kmp+二分,二分枚举答案的长度,用kmp判断是否合法 #include <bits/stdc++.h> using namespace std; #define rint register int #define rll register long long #define long long ll const int maxn = 1e6 + 100; char a[maxn], b[maxn]; int pi[maxn], f[maxn];

uva 1358 - Generator(KMP+期望)

题目链接:uva 1358 - Generator 题目大意:给定n,表示有n中字符,然后给定一个字符串S,一开始字符串为空,现在每次随机生成一个1~n的字符添加到字符串末尾,问说字符串包含S为子串的生成次数期望. 解题思路:首先要对S进行预处理,求出失配数组. 定义dp[i]表示末尾部分匹配了i个S串所需要的次数期望,每次枚举可能出现的字符1~n.对于S字符串,i+1肯定是确定的字符,所以对于其他字符肯定是不匹配的. 假设现在生成了k字符,并且说k字符不等于S[i+1],那么根据S的失配数组,

Uva 12012 Detection of Extraterrestrial 求循环节个数为1-n的最长子串长度 KMP

题目链接:点击打开链接 题意: 给定一个字符串str 求字符串str的 循环节个数为 1-len 个的 最长子串长度 思路:套用kmp的性质 #include<string.h> #include<stdio.h> #include <iostream> using namespace std; #define n 1300 void getnext(char str[n],int next[n]){ int m=strlen(str); next[0]=next[1]

UVA 1358 - Generator(dp+高斯消元+KMP)

UVA 1358 - Generator 题目链接 题意:有m种字符(从'A'开始往后数的大写字母),现在有一个字符串,长度不超过12,现在每次随机生成一个字母,要求能产生该字符串的期望长度 思路:dp[i]表示产生长度i的期望长度,那么每次产生一个字符,对应m种转移,每种转移的概率为1/m,转移后的长度可以利用KMP的next数组去快速获得,然后由于转移可能形成环的情况,所以无法直接DP,利用高斯消元去解方程组 代码: #include <cstdio> #include <cstri