本文纯属个人见解,是对后面学习的总结,如有描述不正确的地方还请高手指正~
查看原文:http://wavelee.info/2013/05/04/c-language-programming-paradigm-lserch/
言引
据数序排与搜索在任何语言程编中都非常见常且经常使用,并且经常须要实现不同据数类型的搜索。对于据数范围较比小,且未序排的据数(如从传感器采集来的据数)要查到某个据数的话,一般应用的是线性搜索。对于整数类型据数的搜索,可以应用似类上面的方法来实现:
int lsearch( int key, int array[], int size) { for(int i=0; i<size; 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<n; 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<n; 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<n; 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); }
结果:
可以看到,这个函数实现了我们须要的能功。
以上两种方法都可以实现范类型的的线性搜索。比较方法二和方法一可以看到:两个方法实现的效果都一样,方法二的效率可能会高一些,因为晓得了据数类型写cmpfn的,而方法一只能一个字节一个字节的去较比。效率较低。
查看原文:http://wavelee.info/2013/05/04/c-language-programming-paradigm-lserch/
文章结束给大家分享下程序员的一些笑话语录:
乔布斯:怎么样还是咱安全吧!黑客:你的浏览器支持国内网银吗?苹果可以玩国内的网游吗乔布斯:......不可以黑客:那我研究你的漏洞干嘛,我也需要买奶粉!