打印

MCU如何实现数据查找索引?

[复制链接]
10888|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fight281|  楼主 | 2021-7-27 17:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
一周一天班| | 2021-7-27 18:56 | 只看该作者
卡号得到32位或16位累加和,把这个做数组索引,指向卡号信息地址。为避免重复,卡号多加两位自定义值,存储时检查是否有重复,有则自定义值加,直到唯一。

使用特权

评论回复
评论
dalarang 2021-9-7 19:13 回复TA
你这个思路感觉似曾相识啊,哈希表的做法? 
板凳
wood2qin| | 2021-7-27 19:40 | 只看该作者
数据排序存入。二分法查找。能省不少时间。顺序查太费了。

使用特权

评论回复
地板
fight281|  楼主 | 2021-7-27 21:43 | 只看该作者
一周一天班 发表于 2021-7-27 18:56
卡号得到32位或16位累加和,把这个做数组索引,指向卡号信息地址。为避免重复,卡号多加两位自定义值,存储 ...

谢谢!换成CRC16是否可行?

使用特权

评论回复
5
fight281|  楼主 | 2021-7-27 21:43 | 只看该作者
wood2qin 发表于 2021-7-27 19:40
数据排序存入。二分法查找。能省不少时间。顺序查太费了。

好的,我学习一下,谢谢!

使用特权

评论回复
6
一周一天班| | 2021-7-27 22:31 | 只看该作者
可以,不建议二分法,因为数据是多字节的。采样数据库索引方式比较好。

使用特权

评论回复
7
coody| | 2021-7-28 09:56 | 只看该作者
类似的查找(我用得最多的是串口不定长字符命令),我都是对字符串计算CRC16校验,再加一个字符串映射序号。为了方便查找(比如二分法),对CRC16值进行排序。先计算字符串的CRC16值,读取其映射序号,再读取字符串比较,几万个记录,都可以几十us之内查到。

使用特权

评论回复
8
li880wert| | 2021-7-30 08:36 | 只看该作者
要想快按数据库像做索引,按位或字节分段,分开存放,

使用特权

评论回复
9
xyz549040622| | 2021-7-31 21:11 | 只看该作者
coody 发表于 2021-7-28 09:56
类似的查找(我用得最多的是串口不定长字符命令),我都是对字符串计算CRC16校验,再加一个字符串映射序号 ...

确实是个很好的办法,学习了,不过几十us的速度,有这么快吗?太不可思议了

使用特权

评论回复
10
William1994| | 2021-8-1 21:01 | 只看该作者
卡号高地位所有字节加起来,取0x37的余数,这个hash运算比crc要快。
然后留一个字节,给解决冲突的时候用。

使用特权

评论回复
11
coody| | 2021-8-2 16:08 | 只看该作者
xyz549040622 发表于 2021-7-31 21:11
确实是个很好的办法,学习了,不过几十us的速度,有这么快吗?太不可思议了 ...

几十us都是慢的了。
计算好CRC16,然后顺序排列好,假设有32768个,则2分法查找,只需要查15次,每次读出CRC16比较,现在的MCU通常不需要2us一次(比如用STC8系列的8位机,M0、M3、M4等等32位机),所以30us之内一定可以完成。
假设顺序查找32768次,最长也是在几十ms内。

使用特权

评论回复
12
m564522634| | 2021-8-2 19:18 | 只看该作者
哈希表

使用特权

评论回复
13
fight281|  楼主 | 2021-8-6 16:08 | 只看该作者

最近看到了哈希索引,感觉非常不错,哈希的索引速度还是不错的,就是还没有实验哈希的冲突多不多。

使用特权

评论回复
14
fight281|  楼主 | 2021-8-6 16:11 | 只看该作者
William1994 发表于 2021-8-1 21:01
卡号高地位所有字节加起来,取0x37的余数,这个hash运算比crc要快。
然后留一个字节,给解决冲突的时候用。 ...

一个字节够么?按照目前项目的估算 模值应该是在2000左右,就是不晓得留多少余量,多留3个不知道够不够?

使用特权

评论回复
15
fight281|  楼主 | 2021-8-6 16:17 | 只看该作者
li880wert 发表于 2021-7-30 08:36
要想快按数据库像做索引,按位或字节分段,分开存放,

如果这样的话 4个字节的数据是不是需要很大空间?计算机可以实现,但放单片机上太难了吧?外设的存储也没有这么大的。

使用特权

评论回复
16
m564522634| | 2021-8-9 09:11 | 只看该作者
fight281 发表于 2021-8-6 16:17
如果这样的话 4个字节的数据是不是需要很大空间?计算机可以实现,但放单片机上太难了吧?外设的存储也没 ...

上轻量级的数据库吧,flashDB, 或者sqlitt  我建议你用flashDB稳定速度也不错,数据库本身就是做这个活的他们对搜索优化做的肯定不错,你自己也不用搞那么多的事出来。

使用特权

评论回复
17
fight281|  楼主 | 2021-8-10 15:29 | 只看该作者
m564522634 发表于 2021-8-9 09:11
上轻量级的数据库吧,flashDB, 或者sqlitt  我建议你用flashDB稳定速度也不错,数据库本身就是做这个活 ...

谢谢指点,我研究一下。

使用特权

评论回复
18
xinyue_z| | 2021-8-20 09:24 | 只看该作者
综合以上所有的回复得出的方法:首先对存储数据进行hash处理,然后按照hash值对存储的数据进行排序,这其中肯定有很多hash相同的。在相同的hash值的数据中使用第二种hash算法,对相同第一种hash的数据进行二次排序。最后为第一次hash建立一个索引(映射表:hash值多少存储地址从哪里开始)按hash值排序,在查找时计算刷卡的第一次hash值,二分法在索引中进行查找,找到首地址和尾地址(下一个hash值的首地址),如果相同的hash值比较多,再按照第二种hash算法二分法查找,如果比较少,就直接比较法查找

使用特权

评论回复
19
fight281|  楼主 | 2021-9-7 11:48 | 只看该作者
xinyue_z 发表于 2021-8-20 09:24
综合以上所有的回复得出的方法:首先对存储数据进行hash处理,然后按照hash值对存储的数据进行排序,这其中 ...

感谢指点!在UINT32取值范围内取2000个数,第一次的hash我测试了一下,重复最多的找5~8之间,请问二次hash一般都怎么处理?

使用特权

评论回复
20
xinyue_z| | 2021-9-7 14:12 | 只看该作者
fight281 发表于 2021-9-7 11:48
感谢指点!在UINT32取值范围内取2000个数,第一次的hash我测试了一下,重复最多的找5~8之间,请问二次has ...

如果一次hash重复的数值比较少的话就没有必要做二次hash了,直接在相同的hash值序列中循环查找就行了。如果重复的很多,选择另一个hash算法,比如简单的单字节累加求和,异或等然后再相同的一次hash序列中按照二次hash的结果排序,在查找的时候,一次hash以后在相同的序列中折半查找。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

45

帖子

2

粉丝