排序,查找,qsort和bsearch的简单总结,scanf字符串截取

有一些时候,一些方便用户做的设计,往往会降低产品本身的安全性。

安全性与易用性,是一道产品设计者需要仔细思考的题。

==========================================================================================================

好了,切入正题。最近在练题,或者说刷题,发现自己不知道的东西还真不少,得好好补补啦~

首先就是c语言的两个,也是唯一的两个与排序搜索相关的函数,记得之前自己还很仔细的去背快速排序法了,原来c里面有的。

标准库里面为数不多的两个实用函数。

它们都在stalib.h头文件中。

1、函数名: qsort 

功  能: 使用快速排序例程进行排序

用  法: void qsort(void *base, int nelem, int width, int (*fcmp)());

base是待排序的数组,nelem是数组元素的个数, width是元素的大小,一般sizeof, fcmp是比较的函数。

参考实用方法:

typedef struct
{
	int h,l,t;
}NODE;
int cmp(const void *q, const void *p)
{
	return (*(NODE*)q).t - (*(NODE *)p).t;//从小到大排,q-p;  从大到小排p-q; 或者:返回值小于0保持现状,大于0交换
}
调用:
qsort(bg, n, sizeof(NODE), cmp);

2、函数名: bsearch 

功  能: 二分法搜索

用  法: void *bsearch(const void *key, const void *base, size_t *nelem,

size_t width, int(*fcmp)(const void *key, const *));

key是待搜索的关键字,  base是待搜索的数组, nelem是数组元素个数, width是元素大小, fcmp是比较函数,它一般和排序的函数是对应的。

返回值是搜索到的元素的地址,没有找到的时候,为null。

这里要注意的是,fcmp中使用的比较类型是数组元素的类型,因此key也必须是对应的数组元素类型。

bsearch的具体用法我参考了源代码才发现。

minix系统中提供:
void * bsearch(register const void *key, register const void *base,
    register size_t nmemb, register size_t size,
    int (*compar)(const void *, const void *))
{
    register const void *mid_point;
    register int  cmp;

    while (nmemb > 0) {
        mid_point = (char *)base + size * (nmemb >> 1);
        if ((cmp = (*compar)(key, mid_point)) == 0)
            return (void *)mid_point;
        if (cmp >= 0) {
            base  = (char *)mid_point + size;
            nmemb = (nmemb - 1) >> 1;
        } else
            nmemb >>= 1;
    }
    return (void *)NULL;
}

linux系统中提:
void *bsearch(const void *key, const void *base, size_t num, size_t size,
          int (*cmp)(const void *key, const void *elt))
{
    size_t start = 0, end = num;
    int result;

    while (start < end) {
        size_t mid = start + (end - start) / 2;

        result = cmp(key, base + mid * size);//传进来的key就是比较的key
        if (result < 0)
            end = mid;
        else if (result > 0)
            start = mid + 1;
        else
            return (void *)base + mid * size;
    }

    return NULL;
}

因此,参考的使用方法:

NODE *q,temp;
in[strlen(in)-1] = '\0';
strcpy(temp.magic,in+1);
q = (NODE *)bsearch(&temp,words, t, sizeof(NODE), cmp1);//传入temp的类型应该和  要搜索的数组的元素类型一致。
if( q== NULL)
	printf("what?\n");
else
	printf("%s\n",(*q).func);

int cmp1(const void *p, const void *q)<span style="white-space:pre">		</span>//qsort中使用的方法
{
<span style="white-space:pre">	</span>return strcmp( (*(NODE *)p).magic, (*(NODE *)q).magic);
}
							

3、关于scanf中读取字符串特殊用法:

这个总是忘记,或者模糊,这里做个笔记。

scanf("%20[^\n]",&a);读字符串20个字节到\n 就结束;

sscanf(in,"%[^]]",deal);将in中的字符串 按照"%[^]]" 规则提取到 deal中;

排序,查找,qsort和bsearch的简单总结,scanf字符串截取

时间: 2024-12-11 16:06:08

排序,查找,qsort和bsearch的简单总结,scanf字符串截取的相关文章

查找总结(一)-----简单查找和折半查找

先介绍一个概念,平均查找长度(ASL)为每一个关键字出现的概率*查找该关键所进行比较的次数,所有关键字这样的值之和 一.简单查找 简单查找,也就是一个个地比较了,不多说 int Easy_find(char c[],int n,char key) { int i=0; while (i<n&&c[i]!=key) { i++; } if (i<n) { return i; } else { return NO_FIND; } } 时间复杂度分析:while循环最少比较1次,最多

Java数据结构 遍历 排序 查找 算法实现

1. 遍历算法(遍历二叉树6种方法) 1.1. 概述 遍历算法针对二叉树而言的,主要有先序.中序.后序三种遍历顺序,三种顺序又分别有递归和常规算法,二叉树遍历的主要思想是:遍历左子树,遍历右子树,访问根节点,由这三者的遍历顺序来确定是先序.中序还是后序.下面只要求掌握递归遍历算法,常规遍历算法见附录一. 1.2. 先序遍历算法 遍历顺序:访问根节点,遍历左子树,遍历右子树.代码如下: void preOrder(BinaryTreeNode bt) { if (bt == null)// 如果当

【转载】Java集合类的排序,查找,替换操作

转自:http://blog.csdn.net/sunhuaqiang1/article/details/52142873 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对象后,我们可以根据Collection中的方法进行排序,查找,替换操作.而不用在东奔西走的利用什么各种排序算法.正则来实现了.在进行数组排序时,有时反而会因为参数问题而大费周折.例如,自己在利用快排进行数组排序时,当将参数(int []

#查找算法#【1】简单查找:顺序、折半查找

•顺序查找 从线性表的一端开始,依次将每个记录的关键字与给定值进行比较,若某个记录的关键字等于给定值,表示查找成功,返回记录序号:若将线性表中所有记录都比较完,仍未找到关键字与给定值相等的记录,则表示查找失败,返回一个失败值. •折半查找 又称为二分查找.这种查找方法要求查找表的数据是线性结构保存,并且还要求查找表中的数据是按关键字由小到大有序排列. 顺序查找比较简单,依次用数组中的每个元素和要查找的元素进行对比即可.不再贴代码说明 折半查找是一种递归过程,每折半一次,可使查找范围缩小一半,当查

C/C++ 排序&amp;&amp;查找算法(面试)

一.排序 1.冒泡排序 1 void BubbleSort(int array[],int n) 2 { 3 int i=0; 4 int j=0; 5 int temp=0; 6 int flag = 0; 7 for(i=0;i<n - 1 ;i++) /*外循环控制排序的总趟数*/ 8 { 9 flag = 0; /*本趟排序开始前,交换标志应为假*/ 10 for(j=n-1;j > i;j--) /*内循环控制一趟排序的进行*/ 11 { 12 if(array[j] < ar

Linux查找和替换目录下所有文件中字符串(转载)

转自:http://rubyer.me/blog/1613/ 单个文件中查找替换很简单,就不说了.文件夹下所有文件中字符串的查找替换就要记忆了,最近部署几十台linux服务器,记录下总结. 查找文件夹下包含字符串的文件 例:查找/usr/local目录下所有包含”rubyer.me”的文件. grep -lr 'rubyer.me' /usr/local/* vim替换单个文件中所有字符串方法 例:替换当前文件中所有old为new :%s/old/new/g #%表示替换说有行,g表示替换一行中

oc将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接

/* 将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接(10分) 如传入:@"good_good_study_good_study" 返回:@"good_study" 如传入:@"I_love_I_hate_love_love" 返回:@"love_I_hate" */ 方法1:选择排序 -(NSString *)sortStringByNumbe

PHP:字符串转数组,数组转字符串;字符串截取、替换、查找

字符串转数组$str = 'one|two|three|four'; print_r(explode('|', $str)); //explode 以字符串分割字符串到数组 $str = 'one two three'; //str_split 以位数分割 $arr1 = str_split($str); $arr2 = str_split($str, 3); print_r($arr1); print_r($arr2); 打印如下:Array ( [0] => o [1] => n [2]

Swift4 字符串截取-超级简单用法

先介绍一下Swift String 自身的方法,后面介绍简单的使用方法 1.截取前面5个字符 let substr = string.prefix(5) 2.截取后面5个字符 let substr = string.suffix(5) 3.获取下标 N 到 M 的字符(0 <= N < M <= string.count) // let string = "12345678" let indexN = string.index(str.startIndex, offs