浅析12306售票算法(java版)
1.以G71列车为例,首先对车次站台进行占位编码(从1开始到最后一站递加)
对以上占位简单描述以下:G71总共18个站点那么我们的单个座位的座位标识可以用十八位长度的二进制字符串表示10000000000000000每一位代表一个站点,每天放票前初始化到下面的订票表中,数据如下余票根据座位标识中的0的个数决定最大余票数量
订票表中的始发受限站点和终到受限站点可以灵活搭配(这个就可以实现限制站点发售)
2.查询余票
如果我们要查询日期为2016-06-11,始发站保定东站(3)到韶关站(15)的G71二等座F座位余票情况只需要执行如下sql(该SQL可以实现选座位和选车厢等功能)
select GUID,车次编码,车次类型,座位类型,车厢号码,座位编码,座位位置 from 订票表
where to_number(substring(座位标识,3,15))=0
and 发车日期='2016-06-11'
and 车次编码='G71'
and substring(始发受限车站,3,4)=1
and substring(终到受限车站,15,16)=1
and 车票状态='待售'
and 车次类型='二等座'
and 座位位置='F'
3.预定票
3.1根据第二步中查询条件获取一条记录然后将车票状态改为锁定
3.2待锁定成功后进行支付
3.2支付成功后然后将保定到韶关的票(000111111111111000这里的始发站标记为0)与原有的票进行或运算,并将车票状态改为待售
100000000000000000 | 000111111111111000 = 100111111111111000 这个时候的余票标识即为动态余票
3.3如果指定时间没有支付,那么可以将这条记录的车票状态恢复为待售
100111111111111000^000111111111111000 = 100000000000000000 这个时候的余票及自动还原回去了
4.退票
获得该车次保定到韶关的票 (000111111111111000)与对应的票进行非运算,则即可回归票池子了
以下为相关java代码
import java.math.BigDecimal; public class MainTest { public static void main(String[] args) { String ticketFlag = ""; int beginStation = ; int endStation = ; long beginTime = System.currentTimeMillis(); String result = orderTicket(ticketFlag, beginStation, endStation); if (result.equals(ticketFlag)) { System.out.println("订票失败"); } else { System.out.println("订票后的结果:" + result); // 如果要取消的话,就进行这个操作 String b = buildTicket(ticketFlag.length(), beginStation, endStation); System.out.println("释放后的结果:" + releaseTicket(ticketFlag, b)); } long endTime = System.currentTimeMillis(); System.out.println("耗时:" + (endTime - beginTime)); } /** * 订票 * * @param ticketFlag * @param beginStation * @param endStation * @return */ private static String orderTicket(String ticketFlag, int beginStation, int endStation) { String result = ""; if (checkCanTicket(ticketFlag, beginStation, endStation)) { String b = buildTicket(ticketFlag.length(), beginStation, endStation); String currentTicked = toTicket(ticketFlag, b); System.out.println("预占票前结果:" + ticketFlag); result = currentTicked; } else { result = ticketFlag; } ; return result; } /** * 取消已定票 * * @param ticketFlag * @param b * @return */ private static String releaseTicket(String ticketFlag, String b) { StringBuilder tempSt = new StringBuilder(""); int length = ticketFlag.length(); for (int i = ; i < length; i++) { char tempA = ticketFlag.charAt(i); char tempB = b.charAt(i); if (tempA == '' && tempB == '') { tempSt.append(""); } else { tempSt.append(tempA); } } return tempSt.toString(); } /** * 创建区间占位票 * * @param length * @param beginStation * @param endStation * @return */ private static String buildTicket(int length, int beginStation, int endStation) { StringBuilder st = new StringBuilder(""); for (int i = ; i < length; i++) { if (i >= beginStation && i < endStation) { st.append(""); } else { st.append(""); } } System.out.println("创建区间票:" + st.toString()); return st.toString(); } /** * 生成订票后的结果 * * @param ticketFlag * @param b * @return */ private static String toTicket(String ticketFlag, String b) { StringBuilder tempSt = new StringBuilder(""); int length = ticketFlag.length(); for (int i = ; i < length; i++) { char tempA = ticketFlag.charAt(i); char tempB = b.charAt(i); if (tempA == '' || tempB == '') { tempSt.append(""); } else { tempSt.append(tempA); } } return tempSt.toString(); } /** * 是否可以订票 * * @param ticketFlag * @param beginStation * @param endStation * @return */ private static boolean checkCanTicket(String ticketFlag, int beginStation, int endStation) { boolean result = false; String tempTicket = ticketFlag.substring(beginStation, endStation); BigDecimal b = new BigDecimal(tempTicket); if (b.equals(new BigDecimal(""))) { result = true; } return result; } }
相关文章
解决idea npm:无法将“npm”项识别为cmdlet、函数、脚本文件或可运行程序的名称问题
在IDEA中运行npm命令时出现无法识别的错误,通常是由于npm环境变量配置不正确引起,解决方法包括以管理员身份运行IDEA,确认node和npm是否正确安装及配置环境变量,需要在系统环境变量中添加node.js的安装路径,并设置npm的全局模块和缓存路径2024-10-10Spring Boot配置文件的语法规则详解(properties和yml)
这篇文章主要介绍了Spring Boot配置文件的语法规则,主要介绍两种配置文件的语法和格式,properties和yml,对于配置文件也有独立的文件夹存放,主要用来存放一些需要经过变动的数据(变量值),感兴趣的朋友跟随小编一起看看吧2024-07-07Java MyBatis传出参数resultType和resultMap解读
这篇文章主要介绍了Java MyBatis传出参数resultType和resultMap解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-12-12
最新评论