OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4889|回复: 13

有关查重的C语言算法讨论、求教??

[复制链接]

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
发表于 2018-2-22 14:08:41 | 显示全部楼层 |阅读模式
10金钱
下面直奔主题了,我这边的需求是:对每次进来的卡号进行查重,卡号的长度为4字节,要求是相同的卡号存进数组只能一个,确保唯一性。(补充:卡号从硬件上拿,有可能相同的卡号,在不同的时间内出现,相当于查重算法是对进来的卡号进行判断是否存进数组)
我的做法是:对进来的卡号一个字节一个字节的对比,连续4个字节相同,则不再存进数组。其中当有一个字节不同时,则跳出判断,数组地址进行偏移(是为了卡号存的地址是连续的),存进数组。
这样的方法首先小批量是可以实现,但是大批量的时候,就比较费时了。
就此,请教各位大侠有没有更有效、更快捷的方法呢?下面是自己写的函数:
[mw_shl_code=c,true]void compare(void)
{        
                //ID去重比较
          u8 CardNum=0,Num=0,counter=0;//counter为相同计数标志
                for( CardNum = 0; CardNum < CardOffSet; CardNum++)
                {                                      
                                for(Num = 0;Num < 4;Num++)
                                {                       
                                        if( IDdata[CardOffSet * 4 + Num] == IDdata[ CardNum * 4 + Num] )        counter++;        //相同counter就加                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
                                        else //不相同就跳出比较,直接发数据
                                        {
                                                counter=0;//清掉计数       
                                                break;               
                                        }
                                }
                               
                                if( counter == 4)         break;                                        //加到8时表示卡号相投,跳出比较,不发数据
                }                       
               
                if(CardOffSet == 0 || counter != 4)                //不相同就跳出比较,直接发数据
                {               
                       
                        CardOffSet++;                //相同CardOffSet则不加,不相同CardOffSet则相加,CardOffSet五分钟后清零               
                        counter=0;
                }               
}[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

先说个别的东西,c标准库里有个strncmp()函数,比较2个字符串的前n个字节是否相同,你想比较字符串的时候用这个就行; 回到问题本身 如果批量大的时候就变慢了那肯定是查找比较费时,不是比较字符串本身的问题; 查找费时是因为你没排序; 但是排序也需要时间的,可以在有操作时查找,空闲时排序。 如果人力一次插入一张卡录入卡号,可以直接插入排序;如果一次录入多个卡号,可以归并排序;如果短时间内从数据线输入大量 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2018-2-22 14:08:42 | 显示全部楼层
先说个别的东西,c标准库里有个strncmp()函数,比较2个字符串的前n个字节是否相同,你想比较字符串的时候用这个就行;

回到问题本身
如果批量大的时候就变慢了那肯定是查找比较费时,不是比较字符串本身的问题;
查找费时是因为你没排序;
但是排序也需要时间的,可以在有操作时查找,空闲时排序。
如果人力一次插入一张卡录入卡号,可以直接插入排序;如果一次录入多个卡号,可以归并排序;如果短时间内从数据线输入大量卡号,那就别查重了,先都存起来,然后排序的时候删掉重复的卡号。
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2018-2-22 14:23:27 | 显示全部楼层
上数据库
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-22 14:44:55 | 显示全部楼层

单片机做,有些有局限性
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12025
金钱
12025
注册时间
2013-3-8
在线时间
1280 小时
发表于 2018-2-22 15:35:05 | 显示全部楼层
转换成32位的直接取异或,如果为0,则为重复的,否则为不重复的。如果卡号可以转为int型,并且数组存放是从大到小或从小到大的方式顺序存放的,则先可以通过二分法找到数据的大致位置范围,然后再通过异或的方式对比。
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-22 20:43:07 | 显示全部楼层
augustedward 发表于 2018-2-22 15:35
转换成32位的直接取异或,如果为0,则为重复的,否则为不重复的。如果卡号可以转为int型,并且数组存放是从 ...

转换成32位直接异或其实过程也跟一个字节一个字节对比效果一样,因为缓存数组是缓存全部的卡号,也就是一个卡号在多个卡号里面对比,也就是在缓存里面找相同的,不同则存进数组。请问还有其他的方式吗
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-22 20:49:24 | 显示全部楼层
xianshasaman 发表于 2018-2-22 16:49
先说个别的东西,c标准库里有个strncmp()函数,比较2个字符串的前n个字节是否相同,你想比较字符串的时候 ...

可以,是的,最关键的是还是要加个排序进去,这样的思路也可以。C的标准库函数,strncmp和strcmp这两个,觉得还是有局限性,
回复

使用道具 举报

6

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
374
金钱
374
注册时间
2012-12-30
在线时间
48 小时
发表于 2018-2-22 21:16:14 | 显示全部楼层
那就牺牲空间换取时间吧
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-23 08:39:02 来自手机 | 显示全部楼层
BG4RFF 发表于 2018-2-22 21:16
那就牺牲空间换取时间吧

其实牺牲内存空间并不能很好的解决问题,况且也不利于后面数据的调用,只能说用于缓兵之计的情景。
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12025
金钱
12025
注册时间
2013-3-8
在线时间
1280 小时
发表于 2018-2-23 08:52:41 | 显示全部楼层
MrXiong 发表于 2018-2-22 20:43
转换成32位直接异或其实过程也跟一个字节一个字节对比效果一样,因为缓存数组是缓存全部的卡号,也就是一 ...

你能存储时按照从小到大,或从大到小的方式排序吗?如果可以的话,用二分法查找,会快很多。
回复

使用道具 举报

0

主题

45

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
224
金钱
224
注册时间
2016-9-14
在线时间
32 小时
发表于 2018-2-23 13:50:08 | 显示全部楼层
深度学习了一把
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-24 09:23:04 | 显示全部楼层
augustedward 发表于 2018-2-23 08:52
你能存储时按照从小到大,或从大到小的方式排序吗?如果可以的话,用二分法查找,会快很多。

现在是在想办法,看怎么排序,如果像您说的直接把数组开成成长度为32,是可以做排序操作,我是在考虑如果不开32长度的数组时,有没有其他的方法可以更好的办法,大神有没有新的想法呢?
回复

使用道具 举报

6

主题

146

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1254
金钱
1254
注册时间
2016-11-30
在线时间
211 小时
 楼主| 发表于 2018-2-24 09:23:43 | 显示全部楼层

一起学习,有什么好的想法也请尽情发言,谢谢
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12025
金钱
12025
注册时间
2013-3-8
在线时间
1280 小时
发表于 2018-2-24 09:53:01 | 显示全部楼层
MrXiong 发表于 2018-2-24 09:23
现在是在想办法,看怎么排序,如果像您说的直接把数组开成成长度为32,是可以做排序操作,我是在考虑如果 ...

你这个主要就是查找判断,用深度学习,神经网络等复杂算法,单片机就处理不了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 20:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表