#include<cstdio>
#include<algorithm>
using namespace std;
int n,k=1,maxi;
double mins;//最小支持度
int d[15][15];//交易数据集
struct item//项集类型
{
int cnt;//元素的个数
int a[15];//项集内的元素
double s;//支持度
};
struct tab//列表类型
{
int cnt;//项集的个数
item it[1005];
}c[15],l[15];
int sia(int di,int x)//在第di个事务中寻找项集的一个单元素子集
{
for(int i=1;i<=d[di][0];i++)
{
if(d[di][i]==x) return 1;
}
return 0;
}
double si(item x)//在d中寻找任意一个项集出现的次数
{
double s=0;
for(int i=1;i<=n;i++)
{
int flg=1;
for(int j=1;j<=x.cnt;j++)
{
if(!sia(i,x.a[j])) flg=0;
}
if(flg) s=s+1;
}
return s;
}
item link(item x,item y)//连接两个项集生成一个新的项集
{
item re;
re.cnt=x.cnt+y.cnt;
for(int i=1;i<=x.cnt;i++) re.a[i]=x.a[i];
for(int i=1+x.cnt;i<=x.cnt+y.cnt;i++) re.a[i]=y.a[i-x.cnt];
sort(re.a+1,re.a+x.cnt+y.cnt+1);//通过排序去除重复的元素
for(int i=1;i<re.cnt;i++)
{
if(re.a[i]==re.a[i+1])
{
for(int j=i+1;j<re.cnt;j++) re.a[j]=re.a[j+1];
re.cnt--;
}
}
re.s=si(re)/n;
return re;
}
void cre(int x)//c[k]->l[k]
{
for(int i=1;i<=c[x].cnt;i++)
{
if(c[x].it[i].s>=mins)
{
l[x].cnt++;
l[x].it[l[x].cnt]=c[x].it[i];
}
}
if(!l[x].cnt ) return;
printf("第%d次迭代产生%d个频繁集:\n",k,l[x].cnt);
for(int i=1;i<=l[x].cnt;i++)
{
for(int j=1;j<=l[x].it[i].cnt;j++) printf("%d ",l[x].it[i].a[j]);
printf("\n");
}
printf("\n");
return;
}
int ex(item t)//项集是否存在
{
int flg=0;//是否有重复的项集
for(int i=1;i<=c[k].cnt;i++)
{
int tf=1;//和第i个项集是否不同
for(int j=1;j<=t.cnt;j++)
{
if(t.a[j]!=c[k].it[i].a[j]) tf=0;//两个项集每一位都相同
}
if(tf) flg=1;//有重复的项集
}
return flg;
}
int main()
{
scanf("%lf",&mins);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int cnt=0,x;
while(1)
{
scanf("%d",&x);
if(x==-1) break;//输入-1代表事务结束
d[i][0]++;//d[i][0]表示第i个事务的商品数
d[i][d[i][0]]=x;
if(x>maxi) maxi=x;//maxi表示不同的元素种类
}
}
for(int i=1;i<=maxi;i++)//生成初始的候选集c[1]
{
double cnt=0;
for(int j=1;j<=n;j++)
{
for(int p=1;p<=d[j][0];p++)
{
if(d[j][p]==i) cnt=cnt+1;
}
}
c[1].it[i].s=0;
c[1].it[i].a[1]=i;
c[1].it[i].cnt=1;
c[1].it[i].s=cnt/n;
c[1].cnt++;
}
cre(1);
while(k)//l[k-1]->c[k]
{
++k;
for(int i=1;i<l[k-1].cnt;i++)
{
for(int j=i+1;j<=l[k-1].cnt;j++)
{
item t=link(l[k-1].it[i],l[k-1].it[j]);
if(t.cnt==k)
{
if(ex(t)) continue;//去重
c[k].cnt++;
c[k].it[c[k].cnt]=t;
}
}
}
cre(k);
if(!l[k].cnt) break;
}
return 0;
}
/*
样例数据
0.2
9
1 2 5 -1
2 4 -1
2 3 -1
1 2 4 -1
1 3 -1
2 3 -1
1 3 -1
1 2 3 5 -1
1 2 3 -1
*/