一个提高查找速度的小技巧

在一个数组中查找某一个元素,或是在一个字符串中查找某个字符,我们一般都会写出如下代码。这样的代码虽然简洁明了,但在数组元素很多的情况下,并不是一个很好的解决方案,今天我就来分享一个提高查找速度的小技巧.

//在一个int数组中查找某个元素
int find(int A[],int n,int element)
{
    for( int i = 0; i < n; i++ )
    {
        if( A[i] == element )
            return i;
    }
    return -1;
}

//在一个字符串中查找某个字符
int find(string& str,char c)
{
    for( int i = 0; i < str.length(); i++ )
    {
        if( str[i] == c )
            return i;
    }
    return -1;
}

虽然每次都是写出这样的代码,但我总觉得for循环中的<判断有点多余,比如数组中有100个元素,我们明明知道前99个是不会数组越界的,根本不需要判断i<n的,但我们却多判断了99次,昨天晚上看编程珠玑的时候发现了这个小技巧,今天就来分享一下。

通过哨兵的方式却掉这多余的判断,将上面两个方法改造如下:

//在一个int数组中查找某个元素
int find1(int A[],int n,int element)
{
    if( n <= 0 )
        return -1;
    if( A[--n] == element )
        return n;

    int hold = A[n];
    A[n] = element;
    int i = 0;
    for( ; ; i++ )
    {
        if( A[i] == element )
            break;
    }
    A[n] = hold;
    return i < n ? i : -1;
}

//在一个字符串中查找某个字符
int find1(string& str,char c)
{
    int n = str.length();
    if( n <= 0 )
        return -1;
    if( str[--n] == c )
        return n;
    int hold = str[n];
    str[n] = c;
    int i = 0;
    for( ; ; i++ )
    {
        if( str[i] == c )
            break;
    }
    str[n] = hold;
    return i < n ? i : -1;
}

我勒个去,怎么变得这么长,但的确是减少了判断的次数,如果数组较大的话提高运行速度肯定是一定的,如果你非要说数组很小的话,说不定速度还要降低呢,那你不这样写不就得了,好了废话少说,虽然代码已经很简单明了了,但我还是简单说一下思路。

就是在数组的末尾加一个哨兵,即使不判断i<n也能确保数组不越界,加了哨兵之后if语句是必然会break的。

先判断最后一个元素的值是不是我们要查找的数,如果是,返回其下标;如果不是,将最后一个数的值保存起来,将要查找的那个数赋给最后一个元素,循环查找指定的元素,不用判断数组越界,if语句必然break,将最后一个元素的值还原,最后只用判断i<n,如果是i即为所求,否则要查找的元素不在数组中。

最后在做一个简单的性能测试,看到底能否提高查找速度。

测试代码如下:

void testFind()
{
    int N = 200000;
    int* A = new int[N];
    A[N-2] = 1; 

    DWORD start = ::GetTickCount64();
    for( int i = 0; i < 10000; i++ )
        find(A,N,1);
    DWORD end = ::GetTickCount64();
    cout <<"优化前:" << end - start <<" 毫秒" << endl; 

    start = ::GetTickCount64();
    for( int i = 0; i < 10000; i++ )
        find1(A,N,1);
    end = ::GetTickCount64();
    cout <<"优化后:" << end - start <<" 毫秒" << endl;
}

运行结果如下:

速度还是会快一点

时间: 2024-10-13 00:13:54

一个提高查找速度的小技巧的相关文章

提高myeclipse性能的小技巧(个人整理)

提高myeclipse性能的小技巧,个人整理,还有很多不全的地方,希望大家提出,共同进步. 1.工具栏的设置 工具栏中有很多不常用的图标,可以通过windows->Customize Perspective自己选择. 2.启动项设置 myeclipse在启动时,会加载相关启动项,其中有很多是我们用不到的容器,我们可以通过相关配置来选择启动与否.如:我不用jboss这个容器,我就去掉勾选,这样,在启动时,就不会加载此容器. 3.设置默认编辑器 大家都碰到过这样的问题,打开一个jsp页面或者html

分享两个提高效率的AndroidStudio小技巧

原文:https://www.jianshu.com/p/68fd5373effc 这次分享两个 Android Studio 的小技巧,能够有效提高效率和减少犯错,尤其是在团队协作开发中. Getter 模板修改--自动处理 null 判断 格式化代码自动整理方法位置--广度 or 深度 好了,下面优先介绍下这两个小技巧有什么作用,然后再给出使用教程,想直接看教程的可以直接跳到最后. 目的 Getter 模板修改 开发过程中,经常会遇到空指针异常,尤其是在线上 bug 中,由于未进行 null

增进编程语言学习速度的小技巧

之前写了一篇<变量提升和执行环境对象>的文章,里面的知识点是去很多书很多资料去找的,相当麻烦,对于一个只是熟悉但并不精通js语言的人来说,有时也并不能把所有疑惑的地方搞清楚. 今天早上重新看自己码过一遍的<单页Web应用>第一章的源码,忽然发现有了感悟.一个小技巧,就是高中那会儿学VB语言的时候,自己并未真正理解VB这门语言,只是反复去抄习题答案里的代码,就把VB学会了.当时对VB的理解,可以完全说是对习题答案里代码的理解,自己靠感觉:“嗯,答案里是这么写的,原来这函数应该这么用,

提高工作效率的小技巧

你是否曾有过这种感觉:当你回顾自己度过的一周时感到消沉,因为你未能完成自身所期望的那么多工作.当你在打造一个成功的职业生涯或你自己的事业时,时间或许是你最宝贵的财富,如何支配你的时间直接决定了你的收入.你无法购买你自有之外的时间,而时钟却永不停息地滴答作响. 几年前,我发现了一个能让我把效率提高近三倍的简单方法,在本文中我将分享一些你可以马上着手进行的非常实用的观念,并且你不必为之付出比现在更多的努力. 使用一个详细的日程表 更好管理时间的首要任务是找出你现在支配时间的方式.使用一个日程表是完成

Linux查找文件内容小技巧

目录 grep ag linux系统查找文件内容最常见的命令有grep和ag grep grep是比较常见的查找命令 # 在当前目录的py文件里查找所有相关内容 grep -a "broadcast" *.py # 在当前目录及子目录里(递归)查找,最后一个参数可以换成指定目录 grep -r "broadcast" . # 在指定目录及子目录里(递归)查找,不区分大小写 grep -r -i "broadcast" /src ag 相比grep

介绍一个二次排序的小技巧(best coder27期1001jump jump jump)

先来描述一下问题: 问题描述 有n小孩在比赛跳远,看谁跳的最远.每个小孩可以跳3次,这个小孩的成绩就是三次距离里面的最大值.例如,一个小孩跳3次的距离分别时10, 30和20,那么这个小孩的成绩就是30.给出每个孩子三次跳的距离,问最终每个孩子的排名是多少. 问题分析:方法1: 由于原问题规模较少,只有两个或三个孩子,可以采用暴力的方法解决,也可满足时间在1s之内(除java代码). 方法2: 由于该问题按孩子跳远距离的最大值进行排序的话,再次按孩子照顺序输出的时候就会出现,由于原顺序未保存而导

加快scanf、printf输入输出速度的小技巧

1 setvbuf(stdin, calloc(1 << 20, sizeof(char)), _IOFBF, 1 << 20); 2 setvbuf(stdout, calloc(1 << 20, sizeof(char)), _IOFBF, 1 << 20); 在数据量比较大的情况下,插入上面两行代码就可以大大加快输入输出速度.它扩大了stdin.stdout缓冲区大小.在同样大小的数据量下,减少了程序对缓冲区操作的次数.

一个清除电脑垃圾的小技巧

我们使用的电脑用的时间长了,会越来越卡,很大的原因是因为在安装时默认安装在C盘,C盘是运行盘,C盘东西多了,显然电脑就会卡 一个好习惯就是平时在安装软件时,自己手动设置安装路径 还有一个办法,就是清理一次C盘,但是C盘很多都是不能删除的,要是一些系统的运行文件不小心删除了,可能会导致你的计算机无法正常运行 给大家一段命令,自动删除系统的垃圾文件:如下 @echo offecho 正在清除系统垃圾文件,请稍等......del/f/s/q %systemdrive%\*.tmpdel/f/s/q

一个查看rpm作用的小技巧

一条命令: rpm -pqi 包全名 根据描述来查看RPM包作用