用算法/伪代码创建分页链接?
有人可以提供代码或者伪代码来说明如何生成StackOverflow上的页面链接吗?
我一直在绞尽脑汁,但是想不出一种合适的方法来构建动态链接,该链接始终显示当前页面的2页,以及第一页和最后一页。
示例:1 ... 5 6 7 ... 593
解决方案
回答
好吧,如果我们知道当前页面,只需将数字减去1,再加上1,然后根据边界检查这些数字并始终显示第一页和最后一页,就很简单了,然后按顺序排列,添加椭圆。
还是我们在询问获取总页数并确定当前页数...?
回答
这些控件通常显示以下控件:P1,Pn,Pc(当前页面),Pc + 1,Pc-1. 这种变化的唯一时间是在分页范围{Pc <P3或者Pc>(Pn-3)}的两端
- 第一步显然是要计算出页数:
numPages = ceiling(totalRecords / numPerPage)
- 如果我们有4个或者更少的数据,这时就辍学了,因为按照上述规则,分页将始终是固定的(P1,P2,Pn-1,Pn),其中一个将是Pc
- 否则,我们有三个"状态"
一种。 (Pc <P3),因此显示P1,P2,P3,Pn,下一步如果Pc> 1,则在P1之前显示"上一个"链接。
b。 (Pc> Pn 2),因此显示上一个,P1,Pn 2,Pn -1,Pn,如果Pc <Pn则显示下一个链接
C。显示上一个,P1,Pc -1,Pc,Pc + 1,Pn,下一个
就像伪代码中的Pie一样容易。在实现时,循环可能会有点麻烦,因为我们必须进行一些迭代才能生成链接。
编辑:
当然上一个和下一个与Pc + / 1相同
回答
public void PageLinks(int currentPage, int lastPage) { if (currentPage > 2) Add('[1]', '...'); for(int i=Math.Max(1, currentPage-1); i< Math.Min(currentPage+1, lastPage); i++) Add('[i]'); if (currentPage < lastPage-1) Add('...', '[lastpage]'); }
lastPage计算为Math.Ceiling(totalRecords / RecordsPerPage)。
嗯。实际上,在当前页面为3的情况下,它仍然显示[1] ... [2] [3] [4] ... [xxx]
我认为在这种情况下省略是多余的。但这就是它的工作原理。
编辑:预览正确设置了代码块的格式,为什么它被弄乱了?当然,它只是伪代码...。但仍然....
回答
已经有其他几个答案,但我想向我们展示我采取的解决方法:
首先,让我们检查一下Stack Overflow如何处理正常情况和边缘情况。我的每个页面都显示10个结果,因此要找出一页的作用,请找到一个标签,该标签的条目少于11个:可用性在今天有效。我们看不到任何显示,这是有道理的。
两页怎么样?查找包含11到20个条目的标签(今天,emacs可用)。我们看到:" 1 2 Next"或者" Prev 1 2",这取决于我们所在的页面。
3页? " 1 2 3 ... 3下一个","上一个1 2 3下一个"和"上一个1 ... 2 3"。有趣的是,我们可以看到Stack Overflow本身不能很好地处理这种边缘情况:它应该显示" 1 2 ... 3 Next"
4页? "下一个1 2 3 ... 4","上一个1 2 3 ... 4下一个","上一个1 ... 2 3 4下一个"和"上一个1 ... 3 4"
最后,让我们看一下一般情况,N页:" 1 2 3 ... N Next"," Prev 1 2 3 ... N Next"," Prev 1 ... 2 3 4 ... N Next", "上一页1 ... 3 4 5 ... N下一页",等等。
让我们根据已经看到的内容进行概括:
该算法似乎具有以下共同特征:
- 如果我们不在首页上,则显示指向上一页的链接
- 一律显示首页号码
- 始终显示当前页码
- 始终显示此页面之前的页面,以及此页面之后的页面。
- 一律显示最后一页
- 如果我们不在最后一页,则显示指向下一步的链接
让我们忽略单个页面的边缘情况,并尝试该算法:(如上所述,实际打印出链接的代码会更加复杂。想象一下我们在每个位置放置页码,上一页或者下一页作为将返回正确网址的函数调用。)
function printPageLinksFirstTry(num totalPages, num currentPage) if ( currentPage > 1 ) print "Prev" print "1" print "..." print currentPage - 1 print currentPage print currentPage + 1 print "..." print totalPages if ( currentPage < totalPages ) print "Next" endFunction
此功能可以正常运行,但不会考虑我们在首页还是最后一页附近。查看上面的示例,如果当前页面在两个或者更多个页面之外,我们只想显示...。
function printPageLinksHandleCloseToEnds(num totalPages, num currentPage) if ( currentPage > 1 ) print "Prev" print "1" if ( currentPage > 2 ) print "..." if ( currentPage > 2 ) print currentPage - 1 print currentPage if ( currentPage < totalPages - 1 ) print currentPage + 1 if ( currentPage < totalPages - 1 ) print "..." print totalPages if ( currentPage < totalPages ) print "Next" endFunction
如我们所见,我们在这里有一些重复。我们可以继续进行清理以提高可读性:
function printPageLinksCleanedUp(num totalPages, num currentPage) if ( currentPage > 1 ) print "Prev" print "1" if ( currentPage > 2 ) print "..." print currentPage - 1 print currentPage if ( currentPage < totalPages - 1 ) print currentPage + 1 print "..." print totalPages if ( currentPage < totalPages ) print "Next" endFunction
只剩下两个问题。首先,我们无法正确打印出一页,其次,如果我们位于第一页或者最后一页,则将打印两次" 1"。让我们一次性清理它们:
function printPageLinksFinal(num totalPages, num currentPage) if ( totalPages == 1 ) return if ( currentPage > 1 ) print "Prev" print "1" if ( currentPage > 2 ) print "..." print currentPage - 1 if ( currentPage != 1 and currentPage != totalPages ) print currentPage if ( currentPage < totalPages - 1 ) print currentPage + 1 print "..." print totalPages if ( currentPage < totalPages ) print "Next" endFunction
实际上,我撒了谎:我们还有一个问题。当我们至少有4页并且在第一页或者最后一页上时,我们会在显示屏上得到一个额外的页面。取而代之的是" 1 2 3 ... 10 Next",而不是" 1 2 ... 10 Next"。为了完全匹配Stack Overflow发生的情况,我们必须检查这种情况:
function printPageLinksFinalReally(num totalPages, num currentPage) if ( totalPages == 1 ) return if ( currentPage > 1 ) print "Prev" print "1" if ( currentPage > 2 ) print "..." if ( currentPage == totalPages and totalPages > 3 ) print currentPage - 2 print currentPage - 1 if ( currentPage != 1 and currentPage != totalPages ) print currentPage if ( currentPage < totalPages - 1 ) print currentPage + 1 if ( currentPage == 1 and totalPages > 3 ) print currentPage + 2 print "..." print totalPages if ( currentPage < totalPages ) print "Next" endFunction
我希望这有帮助!
回答
这是我制作分页链接的方法。以下Java代码只是伪代码。
package com.edde; /** * @author Yang Shuai */ public class Pager { /** * This is a method used to display the paging links(pagination or sometimes called pager). * The totalPages are the total page you need to display. You can get this value using the * formula: * * total_pages = total_records / items_per_page * * This methods is just a pseudo-code. * * * @param totalPages how many pages you need to display * @param currentPage you are in which page now */ public static void printPageLinks(int totalPages, int currentPage) { // how many pages to display before and after the current page int x = 2; // if we just have one page, show nothing if (totalPages == 1) { return; } // if we are not at the first page, show the "Prev" button if (currentPage > 1) { System.out.print("Prev"); } // always display the first page if (currentPage == 1) { System.out.print(" [1]"); } else { System.out.print(" 1"); } // besides the first and last page, how many pages do we need to display? int how_many_times = 2 * x + 1; // we use the left and right to restrict the range that we need to display int left = Math.max(2, currentPage - 2 * x - 1); int right = Math.min(totalPages - 1, currentPage + 2 * x + 1); // the upper range restricted by left and right are more loosely than we need, // so we further restrict this range we need to display while (right - left > 2 * x) { if (currentPage - left < right - currentPage) { right--; right = right < currentPage ? currentPage : right; } else { left++; left = left > currentPage ? currentPage : left; } } // do we need display the left "..." if (left >= 3) { System.out.print(" ..."); } // now display the middle pages, we display how_many_times pages from page left for (int i = 1, out = left; i <= how_many_times; i++, out++) { // there are some pages we need not to display if (out > right) { continue; } // display the actual page if (out == currentPage) { System.out.print(" [" + out + "]"); } else { System.out.print(" " + out); } } // do we need the right "..." if (totalPages - right >= 2) { System.out.print(" ..."); } // always display the last page if (currentPage == totalPages) { System.out.print(" [" + totalPages + "]"); } else { System.out.print(" " + totalPages); } // if we are not at the last page, then display the "Next" button if (currentPage < totalPages) { System.out.print(" Next"); } System.out.println(); } public static void main(String[] args) { // printPageLinks(50, 3); help(500); } public static void test(int n) { for (int i = 1; i <= n; i++) { printPageLinks(n, i); } System.out.println("------------------------------"); } public static void help(int n) { for (int i = 1; i <= n; i++) { test(i); } } public static void help(int from, int to) { for (int i = from; i <= to; i++) { test(i); } } }