Apriori算法的C/C#实现

Apriori算法的C/C#实现

最近研究Web数据挖掘常用算法。主要参考书是:

web数据挖掘/刘兵http://book.360buy.com/10079869.html

数据结构/严蔚敏

c语言程序设计/谭浩强

对于c#实现参考

http://www.codeproject.com/Articles/70371/Apriori-Algorithm

c语言实现部分

我把程序发到了csdn

http://download.csdn.net/detail/jiezou007/4458407

数据结构的选取,还做得不太好,会继续改进,请大牛多多指点。

之后我会比较C#与C的Apriori程序,总结一些区别,谈谈面向对象编程在这个算法上的体现与数据结构的选择问题。

#include <dos.h>
 #include <conio.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #define ItemNumSize 2
 #define TranNumSize 100
 #define LISTINCREMENT 1
 #define OK 1
 #define TRUE 1
 #define FASLE 0
 #define ERROR 0
 #define MAX_ARRAY_DIM 100
 #define MAXSIZE  100
 typedef char ItemType;
 typedef int ElemType;
 float  minSupport,minConfidence;
 //动态内存分配,item用什么数据结构 动态数组,线性表好:数组是整体创建,整体删除的
 typedef struct  
 {
     ItemType *item;//项目
     int length;//当前项目个数
     int listsize;//当前分配的存储容量
 }SqList;
 //事务数组集合
 typedef struct
 {
     SqList r[MAXSIZE+1];
     int Length;
 }TranList;
 
 //初始化项目的线性表
 int InitListSq(SqList &L)
 {
     L.item=(ItemType * )malloc(ItemNumSize *sizeof(ItemType));
     if (!L.item)exit(OVERFLOW);//存储分配失败
     L.length=0;//空表长度为0
     L.listsize=ItemNumSize;//初始化存储容量
     return OK;
 }
 //初始化事务的线性表
 int InitListTran(TranList &TranL)//还有更好的动态分配方式初始化
 {
     for (int i=1;i<=TranNumSize;i++)
     {
         InitListSq(TranL.r[i]);
     }
     return OK;
 }
 //插入项目线性表
 int listInsertSq(SqList &L,int i,ItemType e)
 {
     //在线性表L中第i个位置之前插入新元素e
     //i的合法值为1<=i<=l.listlength+1
     ItemType *newbase,*q,*p;
     if(i<1||i>L.length+1)return ERROR;//i值不合法
     if (L.length>=L.listsize)//当前存储空间已满,添加分配
     {
         //重新分配内存空间
        newbase=(ItemType *)realloc(L.item,(L.listsize+LISTINCREMENT)*sizeof(ItemType));
        if (!newbase)exit(OVERFLOW);
        L.item=newbase;//新基址
        L.listsize+=LISTINCREMENT;//增加存储容量
     }
     q=&(L.item[i-1]);//q为插入位置
     for(p=&(L.item[L.length-1]);p>=q;--p)
         *(p+1)=*p;//插入位置,及之后的元素右移
     *q=e;
     ++L.length;
     return OK;
 }
 void main()
 {
     int c;
     ItemType e;
     SqList L;
     int sn;
     int ItemNum; //项目个数
     int trannum[20]={0}; //事务数量
     char b2[100][10]; 
     char b21[100][10]; 
     TranList TranL;
     SqList L1;
     InitListSq(L);
     InitListTran(TranL);
     printf ("链表长度:%d\n", L.length);  // 线性表当前的元素个数
     printf ("链表大小:%d\n", L.listsize); // 线性表最多可存放元素的个数
     while (1)
     {
         system("cls");
         printf_s("\n          Apriori算法的C语言实现\n");
         printf_s("           1        输入项目集合\n");
         printf_s("           2        添加事务\n");
         printf_s("           3        设定最小支持度与最小置信度\n");
         printf_s("           4        输出结果\n");
         printf_s("           5        退出\n");    
         printf_s("请输入:\n");    
         scanf_s("%d",&c);
         switch (c)
         {
         case 1://构造项目集
             {
                 int it;
                 char ItemValue;
                 system("cls");
                 printf_s("构造项目集\n");
                 printf_s("请输入项目个数:\n");//项目个数
                 scanf_s("%d",&ItemNum);
                 for (it=1;it<=ItemNum;it++)//依次输入每个项目集
                 {
                     fflush(stdin);
                     printf_s("\n请输入第%d个项目的字母(a,b,c,d,e,f,……):\n",it);
                     scanf("%c",&ItemValue);
                     listInsertSq(L,it,ItemValue);
                 }
                 printf_s("\n初始化后,项目集各元素值:\n");
                 for (int i=0;i<L.length;i++)
                 {
                     printf_s("%c\n",L.item[i]);
                 }
                 _getch();
                 break;
             }
         case 2:
             {
                 system("cls");
                 //事务的数据结构,动态数组
                 int i,j;
                 char tranvalue;
                 printf_s("请输入要添加的事务个数:\n");//事务个数
                 scanf_s("%d",&sn);
                 for (i=1;i<=sn;i++)//依次输入每个事务所包含的项目,i应当从0开始
                 {
                     printf_s("请输入第%d个事务包含的项目数:",i);
                     scanf_s("%d",&trannum[i]);
                     fflush(stdin);
                     for (j=1;j<=trannum[i];j++)
                     {
                         fflush(stdin);
                         printf_s("输入事务的第%d个项目:\n",j);
                         scanf_s("%c",&tranvalue);
                         //动态分配内存,插入事务数组集合
                         listInsertSq(TranL.r[i],j,tranvalue);
                     }
                 }
                 printf_s("\n各事务的项目如下:\n");
                 for (i=1;i<=sn;i++)
                 {
                     printf_s("\n第%d个事务\n",i);
                     for (j=0;j<=trannum[i];j++)
                     {
                         printf_s("%c",TranL.r[i].item[j]);
                     }
                 }
                 _getch();
                 break;
             }
         case 3://设定最小支持度与最小置信度
             {
                 system("cls");
                 printf_s("请输入最小支持度与最小置信度(空格隔开):");
                 fflush(stdin);//最好在每个scanf前加上fflush( stdin );
                 scanf_s("%f%f",&minSupport,&minConfidence);
                 printf_s("\n最小支持度为:%2.2f\n",minSupport);
                 printf_s("最小置信度为:%2.2f\n",minConfidence);
                 _getch();
                 break;
             }
         case 4://Apriori算法
             {
                 InitListSq(L1);
                 char generatedCandidate[10];
                 int c[20]={0};
                 int f[20]={0};
                 int jj=1;
                 //得到C1,算法第一行
                 for (int i=0;i<ItemNum;i++)//算法太复杂了,以后改为二叉树
                 {
                     for (int j=1;trannum[j]!=0;j++)
                     {
                         for (int k=0;TranL.r[j].item[k]!=0;k++)
                         {
                             if (L.item[i]==TranL.r[j].item[k])
                             {
                                 c[i]++;
                             }
                         }
                     }
                     //计算F1支持度
                     if (c[i]>=minSupport*trannum[i+1])//两个整数相除得到整数
                     {
                         f[i]=c[i];
                         listInsertSq(L1,jj,L.item[i]);//L1
                         jj++;
                     }
                 }
                 printf_s("F1集合为:\n");
                 int temp1=0;
                 for (int i=0;i<ItemNum;i++)
                 {
                     printf_s("{%c}=%d  ",L.item[i],f[i]);
                     if ((temp1+1)%3==0)
                         printf_s("\n");
                     temp1++;
                 }
                 printf_s("\n");
                 //排序TranL.r[j].item[k]
                 int t;
                 for (int i=1;i<=sn;i++)//每个事务
                 {
                     for (int j=0;j<trannum[j+1];j++)//每个项目
                     {
                         if (TranL.r[i].item[j]>TranL.r[i].item[j+1])
                         {
                             t=TranL.r[i].item[j];
                             TranL.r[i].item[j]=TranL.r[i].item[j+1];
                             TranL.r[i].item[j]=t;
                         }
                     }
                 }
                 //GenerateCandidates函数
                 int j1;
                 j1=L1.length;
                 //把L1->b2[i][]
                 for (int i=0;i<j1;i++)
                 {
                     b2[i][0]=L1.item[i];
                 }
                 int kk=0;
                 for (int i=0;i<L1.length;i++)
                 {
                     generatedCandidate[kk]=L1.item[i];
                     kk++;
                     for (int j=i+1;j<L1.length;j++)
                     {
                         generatedCandidate[kk]=L1.item[i+1];
                         if (generatedCandidate!=0)
                         {
                             char temp;
                             //排序
                             for (int i=0;generatedCandidate[i+1]!=0;i++)
                             {
                                 if (generatedCandidate[i]>generatedCandidate[i+1])
                                 {
                                     temp=generatedCandidate[i];
                                     generatedCandidate[i]=generatedCandidate[i+1];
                                     generatedCandidate[i+1]=temp;
                                 }
                             }
                         }
                     }
                 }
                 int u=0;
                 int v=1;//用V来进行输出各种组合的标识数V=1表示正在进行输出
                 int c2[100]={0};
                 int flag1=1;
                 int counter=0;
                 int temp;
                 //getsupport
                 for (int k=2;b2[0][0]!='\0';k++)
                 {
                     u=0;v=1;
                     for (int i=0;i<100;i++)
                     {
                         c2[i]=0;
                     }
                     for (int i=0;i<j1;i++)
                     {
                         for (int i1=i+1;i1<j1;i1++)
                         {
                             for (int j=0;j<k-2;j++)
                             {
                                 if (b2[i][j]!=b2[i1][j])
                                 {
                                     flag1=0;
                                     break;
                                 }
                             }
                             //进行组合的部分
                             if (flag1==1&&b2[i][k-2]!=b2[i1][k-2])
                             {
                                 for (int j2=0;j2<k-1;j2++)
                                 {
                                     b21[u][j2]=b2[i][j2];
                                 }
                                 b21[u][k-1]=b2[i1][k-2];
                                 u++;
                             }
                             flag1=1;
                         }
                     }
                     counter=0;
                     for (int i=0;i<sn;i++)
                     {
                         for (int i1=0;i1<u;i1++)
                         {
                             for (int j1=0;j1<k;j1++)
                             {
                                 for (int j=0;TranL.r[i+1].item[j]!='\0';j++)
                                 {
                                     if (TranL.r[i+1].item[j]==b21[i1][j1])
                                         counter++;
                                 }
                             }
                             if (counter==k)
                                 c2[i1]++;
                             counter=0;
                         }
                     }
                     j1=0;
                     temp=0;
                     //对U中情况进行选择,选出支持度计数大于2的
                     for (int i=0;i<u;i++)
                     {
                         if (c2[i]>=minSupport)
                         {
                             if (v==1)
                             {
                                 printf_s("\nF%d集合为:\n",k);
                                 v=0;
                             }
                             printf_s("{");
                             for (int j=0;j<k;j++)
                             {
                                 b2[j1][j]=b21[i][j];
                                 printf_s("%c,",b2[j1][j]);
                             }
                             j1++;
                             printf_s("\b}");
                             printf_s("=%d  ",c2[i]);
                             if ((temp+1)%3==0)
                                 printf_s("\n");
                             temp++;
                         }
                     }
                     b2[j1][0]='\0';
                     if (b2[0][0]!='0')
                     {
                         printf_s("\b \n");
                     }
                 }
                 _getch();
                 break;
             }
         case 5:
             {
                 return;
                 _getch();
                 system("cls");
                 break;
             }
         default:
             {
                 printf_s("输入有误请重新输入!\n");
                 _getch();
                 system("cls");
             }
         }
 
     }
 }


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值