范式计算机 c语言,c语言范式编程之lsearch

数据排序与搜索在任何语言编程中都非常常见且常用,并且经常需要实现不同数据类型的搜索。对于数据规模比较小,且未排序的数据(如从传感器采集来的数据)要查到某个数据的话,一般使用的是线性搜索。对于整数类型数据的搜索,可以使用类似下面的方法来实现:

int lsearch( int key, int array[], int size)

{

for(int i=0; i

{

if(array[i] == key)

{

return i;

}

}

return -1;

}

这段程序中,值得注意有两点。一个是由于sizeof(int) ==

4,所以指针每一跳为四个字节,即&array[i+1]

-&array[i]的结果为4。另外一个是array[i] ==

key,每次比较的字节数为sizeof(int)。

现在知道了一个线性搜索函数要知道每次指针跳向下次跳的字节数和如何比较两个数据是否相等。因此,进行范式编程时,除了前面这个函数的几个参数外,必须传入这两个参数,及每个元素的大小,以及如何比较这两个元素。

实现

对于一个要查找的元素key,我们并不知道其大小,因此我们需要将这个元素的地址和大小传入到lserach中。此外,还需要知道要查找数组的大小以便能够知道最多查找的次数,还需要知道每个元素大小以便进行迭代。

方法一:

void *lsearch(void *key, void base, int n, int elemSize)

{

for(int i=0; i

{

void *elemAddr = (char *)base + i*elemSize;

if(memcmp(key,elemAddr,elemSize) == 0)

return e.emAddr;

}

return 0;

}

方法二:

void *lsearch(void *key, void *base ,int n, int elemSize,

int (*cmpfn)(void *,void *))

{

for(int i=0; i

{

void *elemAddr = (char *)base + i*elemSize;

if(cmpfn(key,elemAddr) == 0)

return elemAddr;

}

return NULL;

}

这里,需要注意的是int (*cmpfn)(void *,void

*)中,并没有传入元素的大小,这是因为我们在调用lsearch之前就知道了如何比较两个元素是否相等。当然,这个元素需要调用者自己写。

一个简单的例子

int cmpfn(void *elem1, void *elem2)

{

int *ip1 = elem1;

int *ip2 = elem2;

return *ip1 - *ip2;

}

void *lsearch(void *key, void *base ,int n, int elemSize,\

int (*cmpfn)(void *,void *))

{

int i=0;

for( i=0; i

{

void *elemAddr = (char *)base + i*elemSize;

if(cmpfn(key,elemAddr) == 0)

return elemAddr;

}

return NULL;

}

int main()

{

int array[] = {1,3,5,7,9,11,13,15,17,19};

int key1 = 13;

int key2 = 33;

int *find1 = NULL;

int *find2 = NULL;

find1 = lsearch(&key1,array,sizeof(array)/sizeof(int),\

sizeof(int),cmpfn);

find2 = lsearch(&key2,array,sizeof(array)/sizeof(int),\

sizeof(int),cmpfn);

printf("address of array is:%p\n",array);

printf("address of find1 is:%p\n",find1);

printf("address of find2 is:%p\n",find2);

}

结果:

a4c26d1e5885305701be709a3d33442f.png

可以看到,这个函数实现了我们需要的功能。

以上两种方法都可以实现范类型的的线性搜索。对比方法二和方法一可以看到:两个方法实现的效果都一样,方法二的效率可能会高一些,因为知道了数据类型写cmpfn的,而方法一只能一个字节一个字节的去比较。效率较低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值