#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
using namespace std;
#define supmin 0.3 //最小支持度
int supmin_sum; //最小支持度计数
string pinfanxiang[30][10]; //频繁项
int pinfanjishu[30],p=0,f=0; //频繁项计数
string txtsum[20][10]={}; //记录二维数据
int jilushu=0,shumu=0,yimax=0; //用于统计记录数目
int n; //阶数
string Cn[20][5];
int Cn1[20];
string Ln[20][5];
int Ln1[20];
void Txtsum(ofstream& outf) //扫描txt文档获取数据
{int txtsum_i=-1,txtsum_j=0;
string txt1="begin";
ifstream txt("消费记录.txt");
for(int i=0;txt1!="end";i++)
{txt>>txt1;
jilushu=txtsum_i+1;
if(txt1=="end")
break;
if(txt1=="T")
{txtsum_i++;
txtsum_j=0;
txt>>txt1;
}
else
txtsum[txtsum_i][txtsum_j++]=txt1;
}
outf<<"交易号 购买商品"; //输出获取的记录
for(int i=0;txtsum[i][0]!="";i++)
{outf<<endl<<"T"<<i+1<<" ";
for(int j=0;txtsum[i][j]!="";j++)
{outf<<" "<<txtsum[i][j];shumu+=1;}
}
}
void saomiaoyi(string C1[10],int C11[10]) //扫描一阶项及数目
{for(int i=0,k=0;txtsum[i][0]!="";i++)
for(int j=0;txtsum[i][j]!="";j++)
for(int h=0;;h++)
{if(C1[h]=="")
{C1[k++]=txtsum[i][j];
C11[h]=1;
yimax++;
break;
}
if(txtsum[i][j]==C1[h])
{C11[h]+=1;
break;
}
}
}
void paixu(ofstream& outf,string C1[10],int C11[10]) //进行一阶项排序
{int k;
for(k=0;C1[k]!="";k++);
for(int i=0;i<k-1;i++)
for(int j=0;j<k-i-1;j++)
if(C1[j]>C1[j+1])
{string temp=C1[j+1];
int temp1=C11[j+1];
C1[j+1]=C1[j];C11[j+1]=C11[j];
C1[j]=temp;C11[j]=temp1;
}
outf<<"\n\n1阶候选项:\n";
for(int i=0;C1[i]!="";i++)
outf<<C1[i]<<" "<<C11[i]<<endl; //输出测试
}
void pinfanyi(ofstream& outf,string C1[10],int C11[10]) //判断产生一阶频繁项
{for(int i=0;C1[i]!="";i++)
{if(C11[i]>=supmin_sum)
{pinfanxiang[p][0]=C1[i];pinfanjishu[p++]=C11[i];
}
else
{for(int j=i;C1[j]!="";j++)
{C1[j]=C1[j+1];
C11[j]=C11[j+1];
}
i--;
}
}
for(int i=0;C1[i]!="";i++)
{Ln[i][0]=C1[i];
Ln1[i]=C11[i];
}
outf<<"\n\n1阶频繁项:\n";
for(int i=0;pinfanxiang[i][0]!="";i++)
outf<<pinfanxiang[i][0]<<" "<<pinfanjishu[i]<<endl;
}
void huoquCn(int n) //链接n
{int k,q=0;
for(k=0;Ln[k][n-2]!="";k++); //统计k-1频繁个数
if(n<=2)
for(int i=0;i<k;i++)
for(int j=i+1;j<k;j++) //拿出两个
{Cn[q][0]=Ln[i][0];
Cn[q][1]=Ln[j][0];
q++;
}
else
{for(int i=0;i<k;i++)
for(int j=i+1;j<k;j++) //拿出两个
{int p;
for(p=0;;)
{if(Ln[i][p]==Ln[j][p]) //对比是否满足链接
p++;
else
break;
}
if(p==n-2)
{for(int w=0;w<n-1;w++)
Cn[q][w]=Ln[i][w];
Cn[q][n-1]=Ln[j][n-2];
q++;
}
}
}
}
void chanshengLn(ofstream& outf,int n)
{int ii=0,jj=0,i=0,j=0;
for(i;Cn[i][n-1]!="";i++) //遍历每个Cn
{ii=0;Cn1[i]=0;
while(ii<jilushu) //遍历每条记录
{int sum=0;
for(j=0;j<n;j++) //遍历一个Cn的每个
for(jj=0;txtsum[ii][jj]!="";jj++) //遍历一个记录
if(Cn[i][j]==txtsum[ii][jj])
{sum++;
break;
}
if(sum==n)
{Cn1[i]++;
}
ii++;
}
}
if(Cn[0][n-1]!="")
{outf<<"\n\n"<<n<<"阶候选项:\n";
for(int s=0;Cn[s][n-1]!="";s++)
outf<<Cn[s][0]<<" "<<Cn[s][1]<<" "<<Cn[s][2]<<" "<<Cn[s][3]<<Cn1[s]<<endl;
}
int t=0;
for(int i=0;Cn[i][n-1]!="";i++)
{if(Cn1[i]>=supmin_sum)
{for(int w=0;Cn[i][w]!="";w++)
{pinfanxiang[p][w]=Cn[i][w];
Ln[t][w]=Cn[i][w];
}
pinfanjishu[p++]=Cn1[i];
Ln1[t++]=Cn1[i];
}
}
if(Ln[0][n-1]!="")
{outf<<"\n\n"<<n<<"阶频繁项:\n";
for(int s=0;Ln[s][n-1]!="";s++)
outf<<Ln[s][0]<<" "<<Ln[s][1]<<" "<<Ln[s][2]<<" "<<Ln[s][3]<<Ln1[s]<<endl;
}
}
int main(){
ofstream outf; //输出流
outf.open("输出.txt");
string C1[10]; //一阶项存放
int C11[10]; //一阶项个数存放
Txtsum(outf); //调用Txtsum函数扫描txt文档获取数据
supmin_sum=ceil(supmin*jilushu); //最小支持度计数
outf<<"\n\n数据总行数:"<<jilushu<<" \n最小支持度:"<<supmin<<" \n最小支持度计数:"<<supmin_sum<<endl;
saomiaoyi(C1,C11); //扫描一阶项及数目
paixu(outf,C1,C11); //进行一阶项排序
pinfanyi(outf,C1,C11); //判断一阶频繁项
n=2;
while(Ln[0][n-2]!="")
{huoquCn(n);
chanshengLn(outf,n);
n++;
}
outf<<"\n频繁项 支持数\n";
for(int s=0;pinfanxiang[s][0]!="";s++)
outf<<pinfanxiang[s][0]<<" "<<pinfanxiang[s][1]<<" "<<pinfanxiang[s][2]<<" "<<pinfanjishu[s]<<"\n";
outf.close();
return 0;
}