Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 4412 | Accepted: 1149 |
Description
Input
Output
Sample Input
5 4 t* ?h*s ??e* *s ?*e this the an is
Sample Output
0 1 3 0 2 4 Not match 3
题目大意:输入N,M然后输入N行字符串,由'?','*'和26个小写字母组成,'?'代表任意一个小写字母,'*'代表0个或者多个小写字母,紧接着输入M行字符串,问每行字符串和前面N行字符串中哪些是等价的。
解题方法:经典的DFS+字典树,先建立建立一颗字典树,然后用DFS进行搜索。
#include <stdio.h> #include <vector> #include <iostream> #include <algorithm> #include <string.h> using namespace std; int ans[100005]; int nCount; char str[25]; typedef struct node { vector <int> id; node *next[28]; node() { id.clear(); memset(next, 0, sizeof(next)); } ~node() { id.clear(); } }TreeNode; int GetIndex(char ch) { switch(ch) { case '?': return 26; case '*': return 27; default: return ch - 'a'; } } //建立字典树 void Insert(TreeNode *pRoot, char pstr[], int id) { int nLen = strlen(pstr); TreeNode *p = pRoot; for (int i = 0; i < nLen; i++) { int index = GetIndex(pstr[i]); if (p->next[index] == NULL) { p->next[index] = new TreeNode; } p = p->next[index]; } p->id.push_back(id);//每个单词的结尾保存该单词的编号 } void DFS(TreeNode *pRoot, int index) { if (pRoot->next[27] != NULL) { //忽略掉'*',即'*'代表0个字母 DFS(pRoot->next[27], index); } if (index == strlen(str)) { //如果遍历到了最后一个字母,则把编号加进去 for (int i = 0; i < pRoot->id.size(); i++) { ans[nCount++] = pRoot->id[i]; } return; } //如果字典树和字符串当前都是字母,则同时跳过该字母 if (pRoot->next[GetIndex(str[index])] != NULL) { DFS(pRoot->next[GetIndex(str[index])], index + 1); } if (pRoot->next[26] != NULL) { //如果字典树中当前是'?',直接跳过 DFS(pRoot->next[26], index + 1); } if (pRoot->next[27] != NULL) { //如果字典树中当前是‘*’,则让‘*’代表多个字符 for (int i = index; i < strlen(str); i++) { DFS(pRoot->next[27], i + 1); } } } void DeleteNode(TreeNode *pRoot) { if (pRoot != NULL) { for (int i = 0; i < 28; i++) { DeleteNode(pRoot->next[i]); } } delete pRoot; } int main() { int N, M, nID = 0; scanf("%d%d", &N, &M); TreeNode *pRoot = new TreeNode; for (int i = 0; i < N; i++) { scanf("%s", str); Insert(pRoot, str, nID++); } for (int i = 0; i < M; i++) { nCount = 0; scanf("%s", str); DFS(pRoot, 0); if (nCount == 0) { printf("Not match\n"); } else { sort(ans, ans + nCount); printf("%d", ans[0]); for (int j = 1; j < nCount; j++) { if (ans[j - 1] != ans[j]) { printf(" %d", ans[j]); } } printf("\n"); } } DeleteNode(pRoot); return 0; }