首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

请问数据库二级制形式字段存储的统计方式

2013-01-28 
请教数据库二级制形式字段存储的统计方式?场景如下:假设有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倍,一次类推。

热点排行