查找关键字的函数的编程范式

一、编程范式。

在编写一个查找关键字的函数时,我们会考虑到所要查找的关键字的类型是什么,在什么类型的数据里面查找,以及这个数据的长度等信息。

例如:在一个 len 大小的 数组 中查找一个 整型关键字 。

int *Search_int(int *arr,int len,int key)
{
	for(int i=0;i<len;i++)
	{
		if(arr[i] == key)
		{
			return &arr[i];//假如找到则返回这个值的地址。
		}
	}
	return NULL;
}

但平时我们查找的数据不仅仅只有整型,还可能会查找到其他类型的数据,例如,char型,double型,或者还会在结构体中查找,所以我们需要编写一个查找如何数据类型的数据。

不同的数据,所查找的关键字类型不同,字节大小也不同,判断关键字和数据中是否有一样的函数也不同。所以在编写的函数中的参数列表要有:在什么数据类型中查找,所查找的数据的每个数据单元的字节数,数据的长度,关键字,判断关键字是否在数据中的函数。

例如:

void *Search(void *arr,int elemsize,int len,void* key,CmpFun cmpf)
//参数列表:所要查找的数据,所找数据的每个数据单元的字节数,所找数据的大小,关键字,判断关键字是否在数据里的函数
{ 
	void *tmp;
	for(int i=0;i<len;i++)
	{
		tmp = (char *)arr+i*elemsize;
		//if(memcmp(tmp,key,elemsize) == 0)
		if(cmpf(tmp,key) == 0)//如果关键字在数据里面,则返回所找到的关键字
		{
			return tmp;
		}
	}
	return NULL;//否则返回空
}

用来判断关键字是否在所找数据中的函数,因为数据类型不相同,所以需要编写不同的判断函数也不同。

typedef int (*CmpFun)(void *,void*);//用typedef来给函数取名为CmpFun

typedef struct Student
{
	char name[20];
	int score;
}Student;//定义一个结构体

int Cmp_int(void *vp1,void *vp2)//int *,int *
{
	return *(int*)vp1 - *(int *)vp2;
}//判断整型函数

int Cmp_double(void *vp1,void *vp2)//double *,double *
{
#define EPS 0.0000001
	double tmp = *(double *)vp1 - *(double *)vp2;
	if(-EPS<=tmp && tmp<=EPS)
	{
		return 0;
	}
	else if(tmp < -EPS)
	{
		return -1;
	}
	else
	{
		return 1;
	}
}//判断double型函数

int Cmp_stu_name(void *vp1,void *vp2)
{
	return strcmp(((Student *)vp1)->name ,(char *)vp2);
}//判断结构体中的名字

int Cmp_stu_sco(void *vp1,void*vp2)
{
	return ((Student *)vp1)->score - *(int *)vp2;
}//判断结构体中的分数

完整的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>


typedef int (*CmpFun)(void *,void*);


void *Search(void *arr,int elemsize,int len,void* key,CmpFun cmpf)
{ 
	void *tmp;
	for(int i=0;i<len;i++)
	{
		tmp = (char *)arr+i*elemsize;
		//if(memcmp(tmp,key,elemsize) == 0)
		if(cmpf(tmp,key) == 0)
		{
			return tmp;
		}
	}
	return NULL;
}

typedef struct Student
{
	char name[20];
	int score;
}Student;

int Cmp_int(void *vp1,void *vp2)//int *,int *
{
	return *(int*)vp1 - *(int *)vp2;
}

int Cmp_double(void *vp1,void *vp2)//double *,double *
{
#define EPS 0.0000001
	double tmp = *(double *)vp1 - *(double *)vp2;
	if(-EPS<=tmp && tmp<=EPS)
	{
		return 0;
	}
	else if(tmp < -EPS)
	{
		return -1;
	}
	else
	{
		return 1;
	}
}

int Cmp_stu_name(void *vp1,void *vp2)
{
	return strcmp(((Student *)vp1)->name ,(char *)vp2);
}

int Cmp_stu_sco(void *vp1,void*vp2)
{
	return ((Student *)vp1)->score - *(int *)vp2;
}

int main()
{
	int arr[] = {3,6,8,0,1,30,5};
	int nkey = 10;
	int *p = (int *)Search(arr,sizeof(int),7,&nkey,Cmp_int);
	if(p != NULL)
	{
		printf("%d\n",*p);
	}

	double brr[] = {12.3,45.6,9.4,66.7};
	double dkey = 45.61;
	double *dp = (double *)Search(brr,8,4,&dkey,Cmp_double);
	if(dp != NULL)
	{
		printf("%f\n",*dp);
	}
	
	Student crr[] = {"caocao",85,"liubei",30,"sunquan",100};

	int ikey = 100;
	Student *sp = (Student *)Search(crr,24,3,&ikey,Cmp_stu_sco);

	if(sp != NULL)
	{
		printf("%s,%d\n",sp->name,sp->score);
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值