#include "iostream"
#include "string"
#include "iomanip"
#include "fstream"
using namespace std;
const int MAXN = 250;
const int MAXL = 8;
const int MAXP = 62;
int minlen;
int maxmat;
int curmat;
string f[MAXN+1];
string k[MAXN+1];
int n[2];
int p[MAXP];
char s[MAXP];
char minmat[MAXP];
int match[MAXP][MAXN+1][MAXP];
struct Cha
{
char c;
int f;
};
Cha cha[MAXN][MAXP];
void save(char c, int len)
{
int i, j;
for(i=1; i<=p[len]; i++)
if(cha[len][i].c == c)
{
cha[len][i].f++;
cha[len][0] = cha[len][i];
j = i;
while(cha[len][j-1].f < cha[len][0].f)
{
cha[len][j] = cha[len][j-1];
j--;
}
cha[len][j] = cha[len][0];
return;
}
cha[len][++p[len]].c = c;
cha[len][p[len]].f = 1;
}
bool check(int len)
{
int i, j, t, k = 0;
curmat = 0;
for(i=1; i<=n[0]; i++)
{
for(j=0; j<MAXP; j++)
match[len][i][j] = 0;
if(len==1 && s[1]=='*')
match[len][i][0] = 1;
for(j=1; j<=f[i].length(); j++)
{
switch(s[len])
{
case '*':
for(t=0; t<=j; t++)
if(match[len-1][i][t]==1)
{
match[len][i][j] = 1;
break;
}
break;
case '?':
match[len][i][j] = match[len-1][i][j-1];
break;
default:
if(s[len]==f[i][j-1])
match[len][i][j] = match[len-1][i][j-1];
break;
}
}
for(j=f[i].length(); j>=1; j--)
{
if(match[len][i][j] == 1)
{
k++;
if(j == f[i].length())
curmat++;
break;
}
}
}
if(k<maxmat || k==maxmat && len>=minlen)
return false;
p[len] = 0;
for(i=1; i<=n[0]; i++)
for(j=1; j<f[i].length(); j++)
if(match[len][i][j]==1)
save(f[i][j], len);
return true;
}
bool ok(int len)
{
int i, j, l, t;
for(l=1; l<=len; l++)
{
for(i=n[0]+1; i<=n[0]+n[1]; i++)
{
for(j=0; j<MAXP; j++)
match[l][i][j] = 0;
if(s[1]=='*' && l==1)
match[l][i][0] = 1;
for(j=1; j<=f[i].length(); j++)
{
switch(s[l])
{
case '*':
for(t=0; t<=j; t++)
if(match[l-1][i][t]==1)
{
match[l][i][j] = 1;
break;
}
break;
case '?':
match[l][i][j] = match[l-1][i][j-1];
break;
default:
if(s[l]==f[i][j-1])
match[l][i][j] = match[l-1][i][j-1];
break;
}
}
}
}
for(i=n[0]+1; i<=n[0]+n[1]; i++)
if(match[len][i][f[i].length()]==1)
return false;
return true;
}
void search(int len)
{
if((curmat>maxmat || (curmat==maxmat && len<minlen)) && ok(len))
{
maxmat = curmat;
minlen = len;
for(int i=0; i<=minlen; i++)
minmat[i] = s[i];
}
len++;
if(len==1 || s[len-1]!='*')
{
s[len] = '?';
if(check(len))
search(len);
s[len] = '*';
if(check(len))
search(len);
}
for(int i=1; i<=p[len-1]; i++)
{
s[len] = cha[len-1][i].c;
if(check(len))
search(len);
}
}
int main()
{
ifstream fin("正则.txt");
cout << "输入文件:\n";
n[0] = 0;
n[1] = 0;
p[0] = 0;
string str;
char ch;
while(!fin.eof())
{
fin >> str;
fin >> ch;
if(ch == '+')
{
f[++n[0]] = str;
cout << f[n[0]] << " " << ch << endl;
save(f[n[0]][0], 0);
}
else
{
k[++n[1]] = str;
cout << k[n[1]] << " " << ch << endl;
}
}
for(int i=1; i<=n[1]; i++)
f[n[0]+i] = k[i];
memset(match, 0, sizeof(match));
for(i=1; i<=n[0]+n[1]; i++)
match[0][i][0] = 1;
maxmat = 0;
minlen = 255;
search(0);
cout << "匹配最多文件数:" << maxmat << endl;
cout << "正则表达式为:";
for(i=0; i<=minlen; i++)
cout << minmat[i];
cout << endl;
fin.close();
return 0;
}