1 /*****************************************************
2 copyright (C), 2014-2015, Lighting Studio. Co., Ltd.
3 File name:
4 Author:Jerey_Jobs Version:0.1 Date:
5 Description:
6 Funcion List:
7 *****************************************************/
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12
13 typedef struct
14 {
15 unsigned int count;
16 unsigned int time_stamp;
17 }BARR;//桶的属性
18 /*函数声明*/
19 int accurate(int *wins);
20 void merge(BARR*, int);
21 int estimate(BARR*);
22 void judge_file_pointer_null(FILE *fp);
23
24 int window;//窗口大小
25 int size = 0;//桶的个数
26
27 int main()
28 {
29 //BARR barrel[276];
30 BARR *barrel = (BARR *)malloc(150000 * sizeof(BARR));
31 int i = 0;
32 int data;//接收0 1
33 int *wins;//分配窗口大小的数组
34
35 printf("please input window size:\n");
36 scanf("%d", &window);
37 wins = (int *)malloc(window * sizeof(int));
38
39 //FILE *fp = fopen("./01stream.txt", "r");//打开文件
40 FILE *fp = fopen("./01stream_sample.txt", "r");//打开文件
41
42 judge_file_pointer_null(fp);//文件打开是否失败
43
44 int win_count = 0;//窗口计数
45
46 while (!feof(fp))//扫描流中的数据
47 {
48 fscanf(fp, "%d", &data);
49 win_count++;
50
51 if (win_count < window)
52 {
53 wins[win_count] = data;
54 }
55 else//大于窗口时
56 {
57 wins[win_count % window] = data;//数组下标求模
58 }
59 #if 1
60 if (data == 1)//放入桶中
61 {
62 barrel[size].time_stamp = win_count;
63 barrel[size].count = 1;
64 size++;
65 merge(barrel, size);
66 }
67 #endif
68 }
69 printf("1 estimate count :%d\n", estimate(barrel));
70 printf("1 accurate count :%d\n", accurate(wins));
71
72 fclose(fp);
73 free(wins);
74 free(barrel);
75 system("pause");
76 return 0;
77 }
78
79 /*合并桶*/
80 void merge(BARR barrel[], int length)
81 {
82 int i, j;
83 int count = 0;//记录最多可以存在几个相同
84 int tmp;
85 #if 1
86 //判断有没有桶过期
87 if ((barrel[length - 1].time_stamp > window))
88 {
89 for (i = 0; i < length - 1; i++)
90 {
91 if (barrel[i].time_stamp < (barrel[length - 1].time_stamp - window))//
92 {
93 barrel[i].count = 0;
94 }
95 }
96 }
97 #endif
98
99 //合并
100 for (i = 0; i < length ; i++)
101 {
102 count = 0;//记录窗口中的相同大小的桶的个数
103 for (j = i + 1; j < length ; j++)
104 {
105 if (barrel[i].count == barrel[j].count && (barrel[i].count != 0))
106 {
107 count++;
108 if (count == 1)
109 {
110 tmp = j;//保存时间较久的桶的下标
111 }
112 }
113 }//end of inner for
114 if (count == 2)//如果窗口中有三个相同大小的桶则合并时间最久的两个桶
115 {
116 barrel[i].count = 0;//时间戳小的舍弃,置零
117 barrel[tmp].count *= 2;
118 }
119 }//end of external for
120 }
121
122 /*DGIM估计窗口中1的数目*/
123 int estimate(BARR *barrel)
124 {
125 int i;
126 int estimate_count = 0;
127
128 //打印窗口中的桶
129 for (i = 0; i < size; i++)
130 {
131 if (barrel[i].count != 0)
132 {
133 printf("%d, %d\n",barrel[i].time_stamp, barrel[i].count);
134 }
135 }
136
137 int count = 0;//计数第一个窗口内的值
138 for (i = 0; i < size; i++)
139 {
140 if (barrel[i].time_stamp >= 1000 - window && barrel[i].count != 0)
141 {
142 count++;
143 if (count == 1)
144 {
145 estimate_count += 0.5 * barrel[i].count;//最小时间戳的桶值*0.5
146 }
147 else
148 {
149 estimate_count += barrel[i].count;
150 }
151 }
152 }
153
154 return estimate_count;
155 }
156
157 /*精确计数窗口中1的数目*/
158 int accurate(int *wins)
159 {
160 int accurate_count = 0;
161 for (int i = 0; i < window; i++)
162 {
163 if (*(wins + i) == 1)
164 {
165 accurate_count++;
166 }
167 }
168 return accurate_count;
169 }
170
171 /*判断文件指针是否为空*/
172 void judge_file_pointer_null(FILE *fp)
173 {
174 if (fp == NULL)
175 {
176 printf("file open failed!\n");
177 exit(0);
178 }
179 }