请教数据库二级制形式字段存储的统计方式?场景如下:假设有A,B,C,D,E5种东西,每种有两种状态0,1.如此形成一
请教数据库二级制形式字段存储的统计方式? 场景如下: 假设有A,B,C,D,E5种东西,每种有两种状态0,1.如此形成一系列组合,以二进制形式表示如下: 11111 10000 11000 11100 11000 10001 ... ... ... 现问题是如何以最快效率统计出每种二进制形式出现的次数? 如果不考虑遍历,从集合运算,位运算考虑,有什么好的算法? 假设表中的记录数为1亿,提供的算法需要考虑效率。 用c语言实现或者数学集合运算形式也可。 提供思路也可。 谢谢。 [解决办法] 浪费一点点内存没关系吧。计算各个位上是1的个数就成。
int Count[0x20] = {0}; for (int i = 0; i < Length; ++i)//Length是数据的条数 { ++Count[Value[i] & 0x10]; ++Count[Value[i] & 0x08]; ++Count[Value[i] & 0x04]; ++Count[Value[i] & 0x02]; ++Count[Value[i] & 0x01]; } printf_s("1:%d\n2:%d\n3:%d\n4:%d\n5:%d\n", Count[0x01], Count[0x02], Count[0x04], Count[0x08], Count[0x10]);[解决办法] 那就更简单了。根据东西的种类来计数就成。但这种算法如果东西的种类太多就有些麻烦。
能说说东西种类最多有几种吗?
int Count[0x20] = {0}; for (int i = 0; i < Length; ++i)//Length是数据的条数 { ++Count[Value[i]]; }[解决办法] 感觉你陷入纠结中。帮你总结一下:
1、不管用什么方法,都需要从头到尾算一遍。而顺序计算,编译程序可以很好地优化,效率是很高的。你提到的什么矩阵去处、二进制位运算,也都需要从头到尾取一遍数据吧;
2、考虑一下,是否需要每次更新都要从头计算呢?是不是可以在以前的结果上计算新的数据?
下面是一种常见的,在以前基础上更新数据的场景和方法:
如果可以掌握数据的增、减,先把基准的计数做好,保存起来。
增加、减少记录时,相应变更对应的计数值就行,不必每次从头算一遍。
一开始算好 Count[0x200]个计数值。
当有一条记录xValue减少时,就--Count[xValue]
当有一条记录yValue增加时,就++Count[xValue]
当有一条记录从aValue变更为bValue时,相当于减少aValue、增加bValue
--Count[aValue];++Count[bValue];
我在做项目时的一个准则,供参考:
不要刻意从代码上追求效率;
算法的选择,才是决定效率的关键。
[解决办法] 引用: 引用:那就更简单了。根据东西的种类来计数就成。但这种算法如果东西的种类太多就有些麻烦。 能说说东西种类最多有几种吗? C/C++ code?12345int Count[0x20] = {0};for (int i = 0; i < Length; ++i)//Length是数据的条数{ ++Count[Value[i]];} …… 1. 一共最多有2^5=32种取值,即形如:
00000
00001
......
11111
2. 定义一个一位数组,长度为32
3. 遍历那1亿个组合,并同时更新2中数组里相应的元素。
注意:
a. 遍历是必须的;
b. 这种遍历是线性的,应该没有比这个更快了,即如果遍历10万个数据是1ms的话,那么遍历1亿个数据基本上应该是(1亿/10万)ms
c. 具体到楼主的这个问题,完全可以采用并行遍历,比如用10台机器每台机器遍历1千万,最后将每台机器的结果相加就OK了,这样速度可以提高10倍,一次类推。