浅析12306售票算法(java版)

 更新时间:2016年02月16日 08:59:28   作者:全城热恋  
这篇文章主要介绍了浅析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;
}
} 

相关文章

  • Spring Boot 打包如何将依赖全部打进去

    Spring Boot 打包如何将依赖全部打进去

    这篇文章主要介绍了Spring Boot 打包如何将依赖全部打进去,在pom.xml中引入插件,需要在项目的pom.xml文件中,添加 Maven 插件  spring-boot-maven-plugin,本文结合实例代码介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • springboot2.x集成swagger的方法示例

    springboot2.x集成swagger的方法示例

    这篇文章主要介绍了springboot2.x集成swagger的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Springcloud实现服务多版本控制的示例代码

    Springcloud实现服务多版本控制的示例代码

    这篇文章主要介绍了Springcloud实现服务多版本控制的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Java集合总结

    Java集合总结

    今天小编就为大家分享一篇关于Java集合总结,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java中zip文件压缩与解压之ZipInputStream和ZipOutputStream

    Java中zip文件压缩与解压之ZipInputStream和ZipOutputStream

    这篇文章主要给大家介绍了关于Java中zip文件压缩与解压之ZipInputStream和ZipOutputStream的相关资料,ZipInputStream 和 ZipOutputStream 可以用于处理 ZIP文件格式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • SpringBoot整合Redis管道的示例代码

    SpringBoot整合Redis管道的示例代码

    本文将结合实例代码,介绍SpringBoot整合Redis管道,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • Java 8 中 Function 接口使用方法介绍

    Java 8 中 Function 接口使用方法介绍

    这篇文章主要介绍了Java 8中 Function接口使用方法介绍,Java8中提供了一个函数式接口Function,这个接口表示对一个参数做一些操作然后返回操作之后的值
    2022-06-06
  • Jmeter非GUI模式运行分布式测试

    Jmeter非GUI模式运行分布式测试

    这篇文章主要介绍了Jmeter非GUI模式运行分布式测试,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java打印出所有的水仙花数的实现代码

    Java打印出所有的水仙花数的实现代码

    这篇文章主要介绍了Java打印出所有的水仙花数的实现代码,需要的朋友可以参考下
    2017-02-02
  • Java源码解析LinkedList

    Java源码解析LinkedList

    今天小编就为大家分享一篇关于Java源码解析LinkedList,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01

最新评论