淺析12306售票算法(java版)
1.以G71列車為例,首先對車次站臺進行占位編碼(從1開始到最后一站遞加)
對以上占位簡單描述以下:G71總共18個站點那么我們的單個座位的座位標識可以用十八位長度的二進制字符串表示10000000000000000每一位代表一個站點,每天放票前初始化到下面的訂票表中,數(shù)據(jù)如下余票根據(jù)座位標識中的0的個數(shù)決定最大余票數(shù)量
訂票表中的始發(fā)受限站點和終到受限站點可以靈活搭配(這個就可以實現(xiàn)限制站點發(fā)售)
2.查詢余票
如果我們要查詢?nèi)掌跒?016-06-11,始發(fā)站保定東站(3)到韶關(guān)站(15)的G71二等座F座位余票情況只需要執(zhí)行如下sql(該SQL可以實現(xiàn)選座位和選車廂等功能)
select GUID,車次編碼,車次類型,座位類型,車廂號碼,座位編碼,座位位置 from 訂票表
where to_number(substring(座位標識,3,15))=0
and 發(fā)車日期='2016-06-11'
and 車次編碼='G71'
and substring(始發(fā)受限車站,3,4)=1
and substring(終到受限車站,15,16)=1
and 車票狀態(tài)='待售'
and 車次類型='二等座'
and 座位位置='F'
3.預(yù)定票
3.1根據(jù)第二步中查詢條件獲取一條記錄然后將車票狀態(tài)改為鎖定
3.2待鎖定成功后進行支付
3.2支付成功后然后將保定到韶關(guān)的票(000111111111111000這里的始發(fā)站標記為0)與原有的票進行或運算,并將車票狀態(tài)改為待售
100000000000000000 | 000111111111111000 = 100111111111111000 這個時候的余票標識即為動態(tài)余票
3.3如果指定時間沒有支付,那么可以將這條記錄的車票狀態(tài)恢復(fù)為待售
100111111111111000^000111111111111000 = 100000000000000000 這個時候的余票及自動還原回去了
4.退票
獲得該車次保定到韶關(guān)的票 (000111111111111000)與對應(yīng)的票進行非運算,則即可回歸票池子了
以下為相關(guān)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("訂票后的結(jié)果:" + result); // 如果要取消的話,就進行這個操作 String b = buildTicket(ticketFlag.length(), beginStation, endStation); System.out.println("釋放后的結(jié)果:" + 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("預(yù)占票前結(jié)果:" + 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(); } /** * 創(chuàng)建區(qū)間占位票 * * @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("創(chuàng)建區(qū)間票:" + st.toString()); return st.toString(); } /** * 生成訂票后的結(jié)果 * * @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; } }
相關(guān)文章
Struts2開發(fā) 基本配置與類型轉(zhuǎn)換
本篇文章,小編將為大家介紹關(guān)于Struts2開發(fā) 基本配置與類型轉(zhuǎn)換,有需要的朋友可以參考一下2013-04-04SpringBoot電腦商城項目刪除收貨地址的實現(xiàn)方法
這篇文章主要介紹了SpringBoot項目--電腦商城刪除收貨地址功能實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09Logback 使用TurboFilter實現(xiàn)日志級別等內(nèi)容的動態(tài)修改操作
這篇文章主要介紹了Logback 使用TurboFilter實現(xiàn)日志級別等內(nèi)容的動態(tài)修改操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08MyBatis查詢結(jié)果resultType返回值類型的說明
這篇文章主要介紹了MyBatis查詢結(jié)果resultType返回值類型的說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11如何在springMVC的controller中獲取request
這篇文章主要介紹了如何在springMVC的controller中獲取request,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12