求大神帮我写个二分查找的代码,今天想这个头都懵了。

[复制链接]
1599|22
手机看帖
扫描二维码
随时随地手机跟帖
datouyuan|  楼主 | 2018-10-23 21:11 | 显示全部楼层 |阅读模式
数组中最少会有1个字节为0xff,假如有多个0xff的话,它们在的地址一定是连续的。
查找第一个为0xff的元素下标。
查找最后一个为0xff的元素下标。
假定数组为char a[1024];

相关帖子

datouyuan|  楼主 | 2018-10-23 21:19 | 显示全部楼层
可能描述不够准确,数组中所有的0xff所在地址都是连续的。
假如a[0]到a[10]区间都是0xff,那么其它位置一定没有0xff。

这应该符合二分查找的数据有序的要求。

使用特权

评论回复
sdkdfph| | 2018-10-24 07:46 | 显示全部楼层
可以写,具体沟通q793281484

使用特权

评论回复
mailshichao| | 2018-10-24 08:18 | 显示全部楼层
这样的算法我一般到网上找找源代码再看看

使用特权

评论回复
mohanwei| | 2018-10-24 08:40 | 显示全部楼层
//这种没有排序的数据结构,用不了二分
int pos1=-1,pos2=-1;
for(int i=0;i<sizeof(buff);i++)
{
        if(0xFF == buff[i])
        {
                if(-1 == pos1)//起始位置只能初始化一次
                {
                        pos1 = i;
                }
               
                pos2 = i;//不停更新结束位置
        }
}
//如果数组很大,则可以用状态机来做,略过后面的无用功

使用特权

评论回复
评分
参与人数 1威望 +5 收起 理由
datouyuan + 5
mohanwei| | 2018-10-24 08:43 | 显示全部楼层
如果确认所有FF都是连续的,则在找到pos1后,在后半段里启动二分查找法

使用特权

评论回复
datouyuan|  楼主 | 2018-10-24 10:00 | 显示全部楼层
mohanwei 发表于 2018-10-24 08:43
如果确认所有FF都是连续的,则在找到pos1后,在后半段里启动二分查找法

看来确定第一个0xff是没法用二分法了,有没有什么算法能快速找到第一个0xff?

使用特权

评论回复
datouyuan|  楼主 | 2018-10-24 10:12 | 显示全部楼层
mohanwei 发表于 2018-10-24 08:43
如果确认所有FF都是连续的,则在找到pos1后,在后半段里启动二分查找法

假如有且只有一个0xff,能否有算法快速找到它?
求帮忙。

使用特权

评论回复
ayb_ice| | 2018-10-24 10:17 | 显示全部楼层
直接搜索一遍就行了,才1000个,很快的

使用特权

评论回复
mohanwei| | 2018-10-24 10:26 | 显示全部楼层
datouyuan 发表于 2018-10-24 10:12
假如有且只有一个0xff,能否有算法快速找到它?
求帮忙。

没有

使用特权

评论回复
datouyuan|  楼主 | 2018-10-24 11:38 | 显示全部楼层
本帖最后由 datouyuan 于 2018-10-24 11:45 编辑
ayb_ice 发表于 2018-10-24 10:17
直接搜索一遍就行了,才1000个,很快的

我这是简化问题。
数据实际是在25q32中,有2M,用于模拟环形缓存。有效数据是不为0xff的任意数。
当数据快满时,把最早存入数据的整个分区擦除。

假如flash中存储最后写入的位置,会造成这位置频繁擦除改写。所以想用快速寻找的办法来定位。

使用特权

评论回复
caijie001| | 2018-10-24 12:12 | 显示全部楼层
前提:采用二分法查找时,数据需是排好序的

二分法排序的思想:假设一个数组是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段 中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止;当然要是不存在就返回-1(数组下标不可能为负)。



代码如下:


int Binary_Bearch(int arr[], int sz,int  num)
{
        int mid = 0;
        int left = 0;
        int right = sz - 1;
        assert(arr);
        while (left<=right)
        {
                mid = (left + right) / 2;
                if (num > arr[mid])
                {
                        left = mid + 1;
                }
                else if (num < arr[mid])
                {
                        right=mid-1;
                }
                else if (num == arr[mid])
                {
                        return mid;
                }
        }
                return -1;
}

测试函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>

int main()
{
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int sz = sizeof(arr) / sizeof(arr[0]);
        int num = 8;
        int ret=Binary_Bearch(arr, sz, num);
        printf("%d\n", ret);
        getchar();
        return 0;
}

这里结果肯定就是   7  
---------------------
作者:My_heart_
来源:CSDN
原文:https://blog.csdn.net/My_heart_/article/details/51345864
版权声明:本文为博主原创**,转载请附上博文链接!

使用特权

评论回复
评论
877049204 2018-10-24 14:34 回复TA
学习了 
ayb_ice| | 2018-10-24 13:30 | 显示全部楼层
datouyuan 发表于 2018-10-24 11:38
我这是简化问题。
数据实际是在25q32中,有2M,用于模拟环形缓存。有效数据是不为0xff的任意数。
当数据快 ...

如果是这样

那也需要先找出第一个出现0xff的地方,后面的再二分

使用特权

评论回复
评分
参与人数 1威望 +5 收起 理由
datouyuan + 5
eydj2008| | 2018-10-24 14:04 | 显示全部楼层
可以二分法查找 , 但是不能先找头 ,先找中间, 然后再找头和尾
没经典的二分法快, 但比逐个查找速度快.

方法是: 不断分成二段, 直到找到0XFF, 定位出来了, 就知道在哪一个二分段了, 然后已经缩小了很小的范围了.  再来二分找头 和尾,
有一个缺点,  就是如果0xff  如果只有一个数据, 找起来会比较慢. 和逐个查找差不多了. 如果0xff越长 越容易 .

使用特权

评论回复
eydj2008| | 2018-10-24 14:12 | 显示全部楼层
datouyuan 发表于 2018-10-24 11:38
我这是简化问题。
数据实际是在25q32中,有2M,用于模拟环形缓存。有效数据是不为0xff的任意数。
当数据快 ...

你是想延长FLASH的寿命?

使用特权

评论回复
efen| | 2018-10-24 16:26 | 显示全部楼层
楼主应该是查找没使用的Flash区域

使用特权

评论回复
神奇号| | 2018-10-25 08:33 | 显示全部楼层
你存数据的时候申请2个变量,一个是数据存入的起始地址,一个是数据存入的结尾地址,通过这2个变量来控制删除早期的数据

使用特权

评论回复
你的实现方法有待转换,先找到是哪一页,然后再找页中的位置,都可以用2B法,没有问题的,我就是那么做的

使用特权

评论回复
datouyuan 发表于 2018-10-30 09:02
谢谢,我现在就是这样做的。用普通查找找到第一个空分区,再在前一分区中使用二分法查找。
比完全不用二分 ...

查每一页最后俩字节判断,快又好

使用特权

评论回复
千岁寒| | 2018-11-2 09:56 | 显示全部楼层
U32 SearchLeft(rU32 u32StartIndex);  
U32 SearchRight(rU32 u32StartIndex);  
U32 DichotomyFind(U32 u32LeftIndex,U32 u32RightIndex);
——————————————————————————————————————  
DichotomyFind  搜索到第一个0xFF 后返回 其 Index 并停止:
使用 SearchLeft 向左搜索 0xFF 边界,并返回0xFF的左边界:
使用 SearchRight 向右搜索 0xFF 边界,并返回0xFF的右边界:

使用特权

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

本版积分规则

31

主题

1082

帖子

9

粉丝