周五闲来无事,基于上一篇关于初探12306售票算法(一)-理论,进行了java编码实践供各位读者参考(以下为相关代码的简单描述)
1.1初始化一列车厢的票据信息
/**
* 生成Ticket信息
*
* @param train
* @return
*/
public static List<Ticket> initTicketList(Train train) {
List<Ticket> result = new ArrayList<Ticket>();
Map<String, Integer> seatMap = train.getSeatTotalNum();
for (Entry<String, Integer> entry : seatMap.entrySet()) {
int ticketSize = entry.getValue();
String ticketType = entry.getKey();
for (int i = 0; i < ticketSize; i++) {
int saleChannel = (int) (Math.random() * 10) % 8;
Ticket ticket = new Ticket();
ticket.setSaleChannel(saleChannel);
ticket.setTicketType(ticketType);
ticket.setGuid(UUID.randomUUID().toString());
ticket.setFromDate(train.getFromDate());
ticket.setTicketFlag(CommonUtil.initTicketFlag(train));
ticket.setTrainNo(train.getTrainNo());
result.add(ticket);
}
}
return result;
}
1.2 生成站点购票(比如说第进行移位即可如第1站1,第二站‘10’ 这里返回的十进制的)
/**
* 创建
* @param i
* @param stationNum
* @return
*/
public static String buidTicket(int i, int stationNum) {
BigInteger temp = new BigInteger("0");
for (int j = i; j < stationNum; j++) {
temp = temp.or(new BigInteger(buidTicket(j)));
}
return temp.shiftRight(1).toString();
}
1.3 订票主程序,这里一次只定一张票(A=A|B)
/**
* 根据筛选条件取得对应的车次
* @param ticketStr
* @param ticketList
* @param condition
* @return
*/
public static Order createOrderByCondition(String ticketStr,List<Ticket> ticketList,Map condition){
Order tempOrder = null;
for (Ticket ticket : ticketList) {
BigInteger toTicket = new BigInteger(ticketStr);
BigInteger fromTicket = new BigInteger(ticket.getTicketFlag());
// 如果可以订票,那么久进行扣除库存&&
// (ticket.getSaleChannel()==(ticket.getSaleChannel()|1))
if (canTicket(fromTicket, toTicket)
&&ticket.getTicketType().equals(condition.get("ticketType").toString())
//&&(ticket.getSaleChannel()==(ticket.getSaleChannel()|2))
) {
tempOrder = new Order();
tempOrder.setOrderId(UUID.randomUUID().toString());
tempOrder.setSeatType(ticket.getTicketType());
tempOrder.setTicketFlag(toTicket.toString());
tempOrder.setTrainNO(ticket.getTrainNo());
tempOrder.setFromDate(ticket.getFromDate());
tempOrder.setSaleChannel(ticket.getSaleChannel());
tempOrder.setTicketGuid(ticket.getGuid());
ticket.setTicketFlag(fromTicket.or(toTicket).toString());
break;
}
}
return tempOrder;
}
1.4 判断是否邮票,A=~(~A|B)
/**
* 订票判断是否可以订票
*
* @param fromTicket
* @param toTicket
* @return
*/
private static boolean canTicket(BigInteger fromTicket, BigInteger toTicket) {
return fromTicket.equals(fromTicket.not().or(toTicket).not());
}
2.订单实体(保留必要的订单信息)
1 package com.train.ticket; 2 /** 3 * 订单实体 4 * @author guo_zhifeng 5 * 6 */ 7 public class Order { 8 9 private String orderId; 10 private String ticketGuid;//票据id 11 private String ticketFlag;//订票标记 12 private String seatType;//座位类型 13 private String fromDate;//发车日期 14 private String trainNO;//列车编号 15 private int saleChannel;//销售渠道 16 public String getOrderId() { 17 return orderId; 18 } 19 public void setOrderId(String orderId) { 20 this.orderId = orderId; 21 } 22 public String getTicketGuid() { 23 return ticketGuid; 24 } 25 public void setTicketGuid(String ticketGuid) { 26 this.ticketGuid = ticketGuid; 27 } 28 public String getTicketFlag() { 29 return ticketFlag; 30 } 31 public void setTicketFlag(String ticketFlag) { 32 this.ticketFlag = ticketFlag; 33 } 34 public String getSeatType() { 35 return seatType; 36 } 37 public void setSeatType(String seatType) { 38 this.seatType = seatType; 39 } 40 public String getFromDate() { 41 return fromDate; 42 } 43 public void setFromDate(String fromDate) { 44 this.fromDate = fromDate; 45 } 46 public String getTrainNO() { 47 return trainNO; 48 } 49 public void setTrainNO(String trainNO) { 50 this.trainNO = trainNO; 51 } 52 public int getSaleChannel() { 53 return saleChannel; 54 } 55 public void setSaleChannel(int saleChannel) { 56 this.saleChannel = saleChannel; 57 } 58 59 60 }