当前位置: 首页 > news >正文

Qt学习之路(49): 通用算法

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://devbean.blog.51cto.com/448512/272421
关于Qt的model-view部分就告一段落,今天我们开始新的部分。或许有些朋友觉得前面的部分说得很简单。对此我也没有办法,毕竟,Qt是一个很庞大的库,一时半会根本不可能穷尽所有内容,并且我也有很多东西不知道,有时候也必须去查找资料才能明白。

今天开始的部分是关于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

相关文章:

  • 【转】解决:SecureCRT在Linux下vim显示utf-8编码的文件乱码
  • Qt学习之路(47): 自定义Model之三
  • 用vc++做滚动条控件
  • Qt学习之路(48): 自定义委托
  • 9520个大气笔刷!902个无缝叠加图案!!770个质感纹理!!!
  • Qt学习之路(46): 自定义model之二
  • 解决EntityFramework数据库无法自动迁移解决方法
  • Qt学习之路(45): 自定义model之一
  • 编译原理-词法分析器(DFA,C语言描述,可分析C/C++词法)
  • SQL 表操作
  • Qt学习之路(44): QSortFilterProxyModel
  • UIimage图片在程序Documents目录下的存取
  • Qt学习之路(43): QDirModel
  • java “==”和“ equals”以及instanceof的区别
  • Qt学习之路(42): QStringListModel
  • [case10]使用RSQL实现端到端的动态查询
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • JavaScript-Array类型
  • Lucene解析 - 基本概念
  • PHP 7 修改了什么呢 -- 2
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • Spring Cloud中负载均衡器概览
  • Vue.js-Day01
  • 从0到1:PostCSS 插件开发最佳实践
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 小程序 setData 学问多
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #Ubuntu(修改root信息)
  • #数学建模# 线性规划问题的Matlab求解
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (力扣)1314.矩阵区域和
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • ***原理与防范
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .NET 解决重复提交问题
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET企业级应用架构设计系列之结尾篇
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @Transactional 竟也能解决分布式事务?
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [Android]使用Retrofit进行网络请求
  • [Assignment] C++1
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [BT]BUUCTF刷题第4天(3.22)
  • [Codeforces1137D]Cooperative Game
  • [Docker]十二.Docker consul集群搭建、微服务部署,Consul集群+Swarm集群部署微服务实战
  • [Java并发编程实战] 共享对象之可见性