今天开始的部分是关于Qt提供的一些通用算法。这部分内容来自C++ GUI Programming with Qt 4, 2nd Edition。
 
<QtAlgorithms>提供了一系列通用的模板函数,用于实现容器上面的基本算法。这部分算法很多依赖于STL风格的遍历器(还记得前面曾经说过的Java风格的遍历器和STL风格的遍历器吗?)。实际上,C++ STL也提供了很多通用算法,包含在<algorithm>头文件内。这部分算法对于Qt容器同样也是适用的。因此,如果你想使用的算法在Qt的<QtAlgorithms>头文件中没有包含,那么就可以使用STL的算法代替,这并不会产生什么冲突。这里我们来说几个Qt中的通用算法。虽然这些算法都是很简单的,但是,库函数往往会比自己编写的更有效率,因此还是推荐使用系统提供的函数的。
 
首先是qFind()函数。qFind()函数会在容器中查找一个特定的值。它的参数中有一个起始位置和终止位置,如果被查找的元素存在,函数返回第一个匹配项的位置,否则则返回终止位置。注意,我们这里说的“位置”,实际上是STL风格的遍历器。我们知道,使用STL风格遍历器是可以反映一个位置的。例如下面的例子,i的值将是list.begin() + 1,而j会是list.end():
 
QStringList list; 
list << "Emma" << "Karl" << "James" << "Mariette"; 
 
QStringList::iterator i = qFind(list.begin(), list.end(), "Karl"); 
QStringList::iterator j = qFind(list.begin(), list.end(), "Petra");
 
qBinaryFind()的行为很像qFind(),所不同的是,qBinaryFind()是二分查找算法,它只适用于查找排序之后的集合,而qFind()则是标准的线性查找。通常,二分查找法使用条件更为苛刻,但是效率也会更高。
 
qFill()会使用给定值对容器进行填充。例如:
 
QLinkedList<int> list(10); 
qFill(list.begin(), list.end(), 1009);
 
正如其他基于遍历器的算法一样,qFill()也可以针对容器的一部分进行操作,例如下面的代码将会把vector的前5位设置成1009,而最后5位设置为2013:
 
QVector<int> vect(10); 
qFill(vect.begin(), vect.begin() + 5, 1009); 
qFill(vect.end() - 5, vect.end(), 2013);
 
qCopy()算法可以实现将一个容器中的元素复制到另一个容器,例如:
 
QVector<int> vect(list.count()); 
qCopy(list.begin(), list.end(), vect.begin());
 
qCopy()也可以用于同一容器中的元素的复制。qCopy()操作成功的关键是源容器和目的容器的范围不会发生溢出。例如如下代码,我们将把一个列表的最后两个元素复制给前两个元素:
 
qCopy(list.begin(), list.begin() + 2, list.end() - 2);
 
qSort()实现了容器元素的递增排序,使用起来也很简单:
 
qSort(list.begin(), list.end());
 
默认情况下,qSort()将使用 < 运算符进行元素的比较。这暗示如果需要的话,你必须定义 < 运算符。如果需要按照递减排序,需要将qGreater<T>()当作第三个参数传给qSort()函数。例如:
 
qSort(list.begin(), list.end(), qGreater<int>());
 
注意,这里的T实际上是容器的泛型类型。实际上,我们可以利用第三个参数对排序进行定义。例如,我们自定义的数据类型中有一个大小写不敏感的QString的小于比较函数:
 
bool insensitiveLessThan(const QString &str1, const QString &str2) 

        return str1.toLower() < str2.toLower(); 
}
 
那么,我们可以这样使用qSort()从而可以利用这个函数:
 
QStringList list; 
// ... 
qSort(list.begin(), list.end(), insensitiveLessThan);
 
qStableSort()函数类似与qSort(),所不同之处在于它是稳定排序。稳定排序是算法设计上的一个名词,意思是,在排序过程中,如果有两个元素相等,那么在排序结果中这两个元素的先后顺序同排序前的原始顺序是一致的。举个例子,对于一个序列:a1, a5, a32, a31, a4,它们的大小顺序是a1 < a31 = a32 < a4 < a5,那么稳定排序之后的结果应该是 a1, a32, a31, a4, a5,也就是相等的元素在排序结果中出现的顺序和原始顺序是一致的。稳定排序在某些场合是很有用的,比如,现在有一份按照学号排序的学生成绩单。你想按照成绩高低重新进行排序,对于成绩一样的学生,还是遵循原来的学号顺序。这时候就要稳定排序了。
 
qDeleteAll()函数将对容器中存储的所有指针进行delete操作。这个函数仅在容器元素是指针的情形下才适用。执行过这个函数之后,容器中的指针均被执行了delete运算,但是这些指针依然被存储在容器中,成为野指针,你需要调用容器的clear()函数来避免这些指针的误用:
 
qDeleteAll(list); 
list.clear();
 
qSwap()函数可以交换两个元素的位置。例如:
 
int x1 = line.x1(); 
int x2 = line.x2(); 
if (x1 > x2) 
        qSwap(x1, x2);
 
最后,在<QtGlobal>头文件中,也定义了几个有用的函数。这个头文件被其他所有的头文件include了,因此你不需要显式的include这个头文件了。
在这个头文件中有这么几个函数:qAbs()返回参数的绝对值,qMin()和qMax()则返回两个值的最大值和最小值。

本文出自 “豆子空间” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/272421

Qt学习之路(49): 通用算法的更多相关文章

  1. Qt 学习之路 2(49):自定义只读模型

    Qt 学习之路 2(49):自定义只读模型 豆子 2013年5月5日 Qt 学习之路 2 18条评论 model/view 模型将数据与视图分割开来,也就是说,我们可以为不同的视图,QListView ...

  2. Qt 学习之路 2(53):自定义拖放数据

    Qt 学习之路 2(53):自定义拖放数据 豆子  2013年5月26日  Qt 学习之路 2  13条评论上一章中,我们的例子使用系统提供的拖放对象QMimeData进行拖放数据的存储.比如使用QM ...

  3. Qt 学习之路 2(51):布尔表达式树模型

    Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...

  4. Qt 学习之路 2(39):遍历容器

    Qt 学习之路 2(39):遍历容器 豆子 2013年1月16日 Qt 学习之路 2 29条评论 上一节我们大致了解了有关存储容器的相关内容.对于所有的容器,最常用的操作就是遍历.本章我们将详细了解有 ...

  5. Qt 学习之路 2(38):存储容器

    Qt 学习之路 2(38):存储容器 豆子 2013年1月14日 Qt 学习之路 2 38条评论 存储容器(containers)有时候也被称为集合(collections),是能够在内存中存储其它特 ...

  6. Qt 学习之路 2(32):贪吃蛇游戏(2)

    Qt 学习之路 2(32):贪吃蛇游戏(2) 豆子 2012年12月27日 Qt 学习之路 2 55条评论 下面我们继续上一章的内容.在上一章中,我们已经完成了地图的设计,当然是相当简单的.在我们的游 ...

  7. Qt 学习之路 2(73):Qt 线程相关类

    Home / Qt 学习之路 2 / Qt 学习之路 2(73):Qt 线程相关类 Qt 学习之路 2(73):Qt 线程相关类  豆子  2013年11月26日  Qt 学习之路 2  7条评论 希 ...

  8. Qt 学习之路 2(70):进程间通信

    Qt 学习之路 2(70):进程间通信 豆子 2013年11月12日 Qt 学习之路 2 16条评论 上一章我们了解了有关进程的基本知识.我们将进程理解为相互独立的正在运行的程序.由于二者是相互独立的 ...

  9. Qt 学习之路 2(67):访问网络(3)

    Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...

随机推荐

  1. 浅谈PHP技术应用

    序号:1210-41 黑龙江省高等教育自学考试 本科毕业论文 题    目    浅谈PHP技术 学员姓名    夏滟 专    业    计算机及应用 准考证号    010311192585 指导 ...

  2. IIS 7关闭应用程序池自动回收设置

    在web应用程序中经常有一些任务就需要在Global文件启用一个线程来实现, 那假设我们在自己的ASP.NET应用程序中加入了Quartz.NET框架,并且配置等等都OK了. 这个站点访问量很少,现在 ...

  3. CSS3属性之border-radius

    一.语法: 代码如下: border-radius : none |  <length>{1,4} [/  <length>{1,4} ]? 二.取值: <length& ...

  4. BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划( dp)

    dp乱搞即可...( 我就是这样 A 的.. 后来想改快一点..然后就WA了...不理了 ------------------------------------------------------- ...

  5. Java中 hashCode()方法详解

    先来看下Object源码里hashcode方法: /**     * Returns a hash code value for the object. This method is      * s ...

  6. Laravel OAuth2 (一) ---简单获取用户信息

    前言 本来要求是使用微信进行第三方登陆,所以想着先用 github 测试成功再用微信测试,可是最近拖了好久都还没申请好微信开放平台的 AppID ,所以就只写 github 的第三方登陆吧,估计微信的 ...

  7. C++ ofstream和ifstream详细用法

    转载地址:http://soft.chinabyte.com/database/460/11433960.shtml ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就 ...

  8. asp.net从客户端检测到有潜在危险的Request.Form 值

    asp.net开发中,经常遇到“从客户端检测到有潜在危险的Request.Form 值”错误提示,很多人给出的解决方案是: 1.web.config文档<system.web>后面加入这一 ...

  9. JAVA排序(二) Comparator接口

    接着说关于Comparator接口, java.util Interface Comparator<T>(该泛型指定的是被比较的类),使用该接口不需要在待比较类进行比较操作,即在不修改源码 ...

  10. Part Acquisition(spfa输出路径)

    Part Acquisition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4080   Accepted: 1742 ...