UVA 11019 AC自動機 二維模式串匹配

2021-09-26 05:55:38 字數 1752 閱讀 6038

oj:

簡單翻譯:

給你乙個n*m的字元矩陣t,在給你乙個x*y的字元矩陣p,問p在t中能完全匹配幾個位置。

這個題我們利用ac自動機解決首先要解決兩個問題:

1.要想p與t的的某個位置完全匹配,那麼p的每一行要與t的對應的部分匹配,所以可以把p每一行看成模式串構造出ac自動機。

然後在t中每一行逐一匹配,找到p中的所有模式串,與t中的每乙個匹配點。我們要記錄一些東西,記錄匹配到的串是從t當前行的哪個一列開始匹配,還有匹配到的模式串是哪乙個。我們用count[r][c]表示t中以(r,c)為左上角,與p等大矩形中有多少個完整的行與p對應的位置行完全相同。那麼如果p的第i行出現在t第r行出現匹配,匹配開始的列為c,意味著count[r-i][c]應該加1。最終count[r][c]=p的行數的那些位置,就是乙個匹配點。

2.如果給定的模式串中存在重複的串,如果不對ac自動化機進行改造我們就不能得到想要的結果,因為我們在匹配的時候要記錄當前匹配到的是哪乙個模式串,但是有兩個相同的,怎麼辦,我們該記錄哪乙個?因為匹配到的p中的哪一行不能確定。既然這樣,我們匹配到某個存在重複的模式串之後,我們可以將這個重複的模式串在p中所有可能的行,對應的count位置都進行加1操作,就解決了這個問題。因為他們匹配結果屬於不同的小矩陣,所以對最終的結果沒有影響

**實現:

#include #include #include #define max 10001

#define array_sizeof(t) ((size_t)(&t+1) - (size_t)(&t))

char map[1001][1001];

char p[101][101];

// 記錄小矩陣中匹配了多少對應的行

int match[1001][1001];

typedef structqueue;

typedef structtrie;

trie trie;

int idx(char c);

void push(int data);

int pop();

int isempty();

void buildac();

void insert(char *s,int index);

int queue[max],next,pre,size;

void buildac()

}while(!isempty())

trie.fail[index] = trie.word[pfail][i];

trie.last[index] = trie.val[trie.fail[index]] ? trie.fail[index] :

trie.last[trie.fail[index]];}}

}}void insert(char *s,int index)

}}void init()

}int main()

scanf("%d%d",&x,&y);

for(i=0;ibuildac();

for(i=0;iint node = nextnode;

while(trie.last[node])

curnode = nextnode;

}else}}

}int sum = x;

int res = 0;

for(i=0;i}

}printf("%d\n",res);

}return 0;

}

Uva11468 AC自動機 概率dp

這題把ac自動機和dp結合了下,題意就是給你一些模式串,給你選擇每個字元的概率,讓你選擇l個字元,求不出現模式串的概率。先把模式串都插入ac自動機,用乙個match陣列記錄該節點是否是單詞節點,特別注意下這裡單詞節點可能是從0節點開始,也肯能由字尾構成單詞節點,所以得加一句match i match...

模式串匹配 KMP演算法和AC自動機(二)

部落格 模式串匹配 kmp演算法和ac自動機 二 中講了kmp原理和實現,kmp演算法針對的是單模式串的匹配問題,而ac自動機是能夠解決多模式穿匹配問題的演算法,曾嘗試自己實現乙個ac自動機,但是發現還是挺有難度的,於是在網上看了一些大神的模板,在這裡 學習一下 下面的部落格 kmp 大多 是用來解...

洛谷 5357 模板 AC自動機(二次加強版)

題目描述 給你乙個文字串 s 和 n 個模式串 t 1.n t t1 n 請你分別求出每個模式串 t it i ti 在 s 現的次數。輸入格式 第一行包含乙個正整數 n 表示模式串的個數。接下來 n 行,第 i 行包含乙個由小寫英文本母構成的字串 t it i ti 最後一行包含乙個由小寫英文本母...