Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 4412 | Accepted: 1149 |
Descriptionnode
Inputios
Outputthis
Sample Inputspa
5 4 t* ?h*s ??e* *s ?*e this the an is
Sample Outputcode
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; }