翻页区间切割算法(PHP实现)
时间:2009-02-19
来源:互联网
在Web应用程序中,我们经常会见到同一类数据经过视图层的渲染,以“分页显示”和“翻页链接”的形式展现在客户端。下图是Google搜索结果页中的“翻页链接”。
根据上图不难看出,“翻页区间切割(或称划分)”是把已知总页数划分为N段(n1, n2, ...),每段容纳M(m1, m2,...)个页链接,每个页链接对应一页,由数字编号。这里,我们讨论的“切割”是一个动态过程,而这个动态过程可以建立在静态“划分”的基础上。
在遭遇典型的大数据量和有限的屏幕空间时,翻页区间作为精确的导航系统是必不可少的,它应具备某些固定的属性和智能行为来辅助和引导用户浏览。我们应先针对屏幕显示空间的大小做划分,即给定翻页区间的长度$displaySize(图中Google搜索结果页区间长度是20)。然后我们便可以根据当前显示页$currentPage来动态地切割出它所在的区间范围(图中Google当前显示页是18),须做到让$currentPage处于区间起止页号所包含的范围内。同时,还要确保每次切割是在合理的范围内,不会出现页号溢出的现象,这就需要做一些后续的判断来达到智能化。
现代Web应用程序要求快速响应用户的请求,开发者往往要在用户体验和性能之间做出平衡。翻页区间切割算法首要考虑性能,因为我们主要剖析的是算法本身(貌似是废话 )。下面我们就结合PHP实现的代码来看看,如何做到切割的精确和性能最佳化。
代码清单 翻页区间切割算法
/**
* 获得页区间页号
*
* @param int $currentPage 当前页号
* @param int $totalPages 总页数
* @param int $displaySize 区间容量,默认显示10页
* @return array 返回由区间页号组成的数组
*/
function getPageRange($currentPage, $totalPages, $displaySize = 10) {
if ($totalPages <= 0 || $displaySize <= 0) {
return array();
} elseif ($displaySize > $totalPages) {
$startPage = 1;
$endPage = $totalPages;
} else {
if ($currentPage % $displaySize === 0) {
$startPage = $currentPage - $displaySize + 1;
} else {
while (($currentPage % $displaySize)) {
--$currentPage;
}
$startPage = $currentPage + 1;
}
if ($startPage <= 0) {
$startPage = 1;
}
$endPage = $startPage + $displaySize - 1;
if ($endPage > $totalPages) {
$endPage = $totalPages;
$startPage = $endPage - $displaySize + 1;
}
}
return range($startPage, $endPage);
}函数getPageRange接受三个参数,当前页$currentPage,总页数$totalPages,和翻页区间长度$displaySize,默认是10。根据这三个参数,函数getPageRange会生成一个适当的包含了$currentPage的翻页区间。首先,我们需要排除非法的参数值,对于总页数或区间长度小于零的情况,须加以检查。
然后,我们考察静态划分的思路。如前所述,给定翻页区间长度后,便可用总页数除以长度,得到区间个数。与此同时,我们可分析得知并不是所有区间都含有相同的页数,在极端情况下,还会出现总页数小于给定的翻页区间长度,那么划分或切割的结果将永远只有一个区间。幸运的是,这不会给我们的核心算法带来什么干扰,但我们仍须重视代码的健壮性。所以,我们先考虑极端情况,在运用算法解决核心问题之前,先迅速捕捉只有一页的区间。
接下来,我们便可以看看区间的固有属性了。每个动态切割的区间,都有一个起始页和一个尾页;由于区间彼此存在先后顺序,所以在经过静态划分后,我们始终会得到第一个(首)区间和最后一个(尾)区间,若首尾区间重合,则说明总页数小于给定的翻页区间长度。无论如何,算法需要解决的关键问题是如何找到区间的起始页和尾页,一旦确定这两个元素,便可以使用PHP内置的range函数生成区间内的全部页码。
算法利用当前页$currentPage和翻页区间长度$displaySize做比较,来判断当前页在区间内所处的位置,进而推导出区间起始页和尾页与当前页的偏移量。为了做到完美无缺,我们还要考虑边界溢出的问题,这也非常简单,只需判断起始页和尾页是否介于1和总页数之间即可。
至此,对于代码的分析已经完成。我们来看一下算法的时间效率,通俗地说,算法中的基本操作是求模,算法的执行时间取决于$currentPage与$displaySize的差值,差值越大,则求模次数越多、执行时间越长,呈线性结构。而实际的执行结果则是在瞬间完成的。
下面,我们来结合上面的Google搜索结果页,利用getPageRange函数生成一个翻页区间,输入所需参数:
print_r(implode(',', getPageRange(18, 27, 20)));得到的结果是:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20大家会发现这和Google搜索结果页显示的完全不一样。对,因为Google的翻页区间把当前页强制设置在中间位置上了!嗯,不要灰心,我们仍可以利用getPageRange函数得到与之相匹配的结果,只需把问题再分解一下:
print_r(implode(',', array_merge(getPageRange(17, 17, 10), getPageRange(27, 27, 10))));得到的结果是:
8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
根据上图不难看出,“翻页区间切割(或称划分)”是把已知总页数划分为N段(n1, n2, ...),每段容纳M(m1, m2,...)个页链接,每个页链接对应一页,由数字编号。这里,我们讨论的“切割”是一个动态过程,而这个动态过程可以建立在静态“划分”的基础上。
在遭遇典型的大数据量和有限的屏幕空间时,翻页区间作为精确的导航系统是必不可少的,它应具备某些固定的属性和智能行为来辅助和引导用户浏览。我们应先针对屏幕显示空间的大小做划分,即给定翻页区间的长度$displaySize(图中Google搜索结果页区间长度是20)。然后我们便可以根据当前显示页$currentPage来动态地切割出它所在的区间范围(图中Google当前显示页是18),须做到让$currentPage处于区间起止页号所包含的范围内。同时,还要确保每次切割是在合理的范围内,不会出现页号溢出的现象,这就需要做一些后续的判断来达到智能化。
现代Web应用程序要求快速响应用户的请求,开发者往往要在用户体验和性能之间做出平衡。翻页区间切割算法首要考虑性能,因为我们主要剖析的是算法本身(貌似是废话 )。下面我们就结合PHP实现的代码来看看,如何做到切割的精确和性能最佳化。
代码清单 翻页区间切割算法
/**
* 获得页区间页号
*
* @param int $currentPage 当前页号
* @param int $totalPages 总页数
* @param int $displaySize 区间容量,默认显示10页
* @return array 返回由区间页号组成的数组
*/
function getPageRange($currentPage, $totalPages, $displaySize = 10) {
if ($totalPages <= 0 || $displaySize <= 0) {
return array();
} elseif ($displaySize > $totalPages) {
$startPage = 1;
$endPage = $totalPages;
} else {
if ($currentPage % $displaySize === 0) {
$startPage = $currentPage - $displaySize + 1;
} else {
while (($currentPage % $displaySize)) {
--$currentPage;
}
$startPage = $currentPage + 1;
}
if ($startPage <= 0) {
$startPage = 1;
}
$endPage = $startPage + $displaySize - 1;
if ($endPage > $totalPages) {
$endPage = $totalPages;
$startPage = $endPage - $displaySize + 1;
}
}
return range($startPage, $endPage);
}函数getPageRange接受三个参数,当前页$currentPage,总页数$totalPages,和翻页区间长度$displaySize,默认是10。根据这三个参数,函数getPageRange会生成一个适当的包含了$currentPage的翻页区间。首先,我们需要排除非法的参数值,对于总页数或区间长度小于零的情况,须加以检查。
然后,我们考察静态划分的思路。如前所述,给定翻页区间长度后,便可用总页数除以长度,得到区间个数。与此同时,我们可分析得知并不是所有区间都含有相同的页数,在极端情况下,还会出现总页数小于给定的翻页区间长度,那么划分或切割的结果将永远只有一个区间。幸运的是,这不会给我们的核心算法带来什么干扰,但我们仍须重视代码的健壮性。所以,我们先考虑极端情况,在运用算法解决核心问题之前,先迅速捕捉只有一页的区间。
接下来,我们便可以看看区间的固有属性了。每个动态切割的区间,都有一个起始页和一个尾页;由于区间彼此存在先后顺序,所以在经过静态划分后,我们始终会得到第一个(首)区间和最后一个(尾)区间,若首尾区间重合,则说明总页数小于给定的翻页区间长度。无论如何,算法需要解决的关键问题是如何找到区间的起始页和尾页,一旦确定这两个元素,便可以使用PHP内置的range函数生成区间内的全部页码。
算法利用当前页$currentPage和翻页区间长度$displaySize做比较,来判断当前页在区间内所处的位置,进而推导出区间起始页和尾页与当前页的偏移量。为了做到完美无缺,我们还要考虑边界溢出的问题,这也非常简单,只需判断起始页和尾页是否介于1和总页数之间即可。
至此,对于代码的分析已经完成。我们来看一下算法的时间效率,通俗地说,算法中的基本操作是求模,算法的执行时间取决于$currentPage与$displaySize的差值,差值越大,则求模次数越多、执行时间越长,呈线性结构。而实际的执行结果则是在瞬间完成的。
下面,我们来结合上面的Google搜索结果页,利用getPageRange函数生成一个翻页区间,输入所需参数:
print_r(implode(',', getPageRange(18, 27, 20)));得到的结果是:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20大家会发现这和Google搜索结果页显示的完全不一样。对,因为Google的翻页区间把当前页强制设置在中间位置上了!嗯,不要灰心,我们仍可以利用getPageRange函数得到与之相匹配的结果,只需把问题再分解一下:
print_r(implode(',', array_merge(getPageRange(17, 17, 10), getPageRange(27, 27, 10))));得到的结果是:
8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
作者: davidkoree 发布时间: 2009-02-19
很好 学习
作者: okjoyel 发布时间: 2009-02-23
相当好,学习了
作者: qxhy123 发布时间: 2009-02-23
很好~~~
作者: iamvalen 发布时间: 2009-02-24
学习了,呵呵,支持下

作者: libailin 发布时间: 2009-02-24
正好需要用,过来学习
作者: 0451229 发布时间: 2009-12-03
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28