32.3-5ワイルドカード付きマッチング(自動機)
機能
このプログラムはワイルドカード*付きのパターン列がテキスト列に存在するか否かを判断し,位置情報を記録していないことを判断することができるが,もちろん記録したいことも可能である.
構想
サンプル入力については、有限自動機を図に示すように、ワイルドカードごとに区切られた文字列を独立したものと見なし、KMPアルゴリズムのcomput_を実行します.suffix_functionプロセスでは、各セクションの先頭のfailが上部の末尾を指し、各セクションの末尾のfailが自分を指します(後続の1つのマッチングに失敗した場合、ワイルドカードは任意の長さの任意の文字列に代わることができるため、KMPアルゴリズムのように前に移動する必要はありません).
欠点は一度しか現れない場所を見つけることです.すべての場所を見つけるには、再帰検索しか知りません.
このプログラムはワイルドカード*付きのパターン列がテキスト列に存在するか否かを判断し,位置情報を記録していないことを判断することができるが,もちろん記録したいことも可能である.
:
abccbacbababc
ab*bab*c
:
1
構想
サンプル入力については、有限自動機を図に示すように、ワイルドカードごとに区切られた文字列を独立したものと見なし、KMPアルゴリズムのcomput_を実行します.suffix_functionプロセスでは、各セクションの先頭のfailが上部の末尾を指し、各セクションの末尾のfailが自分を指します(後続の1つのマッチングに失敗した場合、ワイルドカードは任意の長さの任意の文字列に代わることができるため、KMPアルゴリズムのように前に移動する必要はありません).
#include<stdio.h>
#include<string.h>
#define maxm 1000
typedef struct e{
char letter;/* ( )*/
int end;/* * , end 1*/
int fail;/* π */
}e;
typedef struct MAC{
int n;/* * */
e p[maxm+1];
}MAC;
MAC initmac(void)
{
char p[maxm];
scanf("%s",p);
int i,l,k=0;
l=strlen(p);
MAC mac;
mac.p[0].end=1;/* , 0*/
for (i=0;i<l;i++)
if (p[i]!='*')
{
k++;
mac.p[k].end=0;
mac.p[k].letter=p[i];
}
else
mac.p[k].end=1;
mac.n=k;
return mac;
}
int computfail(MAC *mac)/* , , */
{
int q,i;
int n=mac->n;
e *p=mac->p;
q=0;
for (i=1;i<=n;i++)
if (p[i].end)/* * ,fail */
{
p[i].fail=i;
q=i;
}
else
if (p[i-1].end)/* , KMP */
{
p[i].fail=i-1;
q=i-1;
}
else/* KMP , π */
{
while ((!p[q].end)&&(p[q+1].letter!=p[i].letter))
q=p[q].fail;
if (p[q+1].letter==p[i].letter)
q++;
p[i].fail=q;
}
return 0;
}
int match(MAC *mac,char t[])/* KMP */
{
int i,l=strlen(t),q=0;
int n=mac->n;
e *p=mac->p;
for (i=0;i<l;i++)
{
while ((!p[q].end)&&(p[q+1].letter!=t[i]))
q=p[q].fail;
if (p[q+1].letter==t[i])
q++;
if (q==n)
return 1;/* KMP , , , */
}
return 0;
}
int main(void)
{
char t[maxm];
scanf("%s",t);
MAC mac;
mac=initmac();
computfail(&mac);
int ans;
ans=match(&mac,t);
printf("%d
",ans);
return 0;
}
欠点は一度しか現れない場所を見つけることです.すべての場所を見つけるには、再帰検索しか知りません.