你的位置:首页 > Java教程

[Java教程]初探12306售票算法(二)


1.订票工具类

 1 package com.train.util; 2  3 import java.io.BufferedWriter; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.OutputStreamWriter; 7 import java.math.BigInteger; 8 import java.util.ArrayList; 9 import java.util.HashMap; 10 import java.util.List; 11 import java.util.Map; 12 import java.util.Map.Entry; 13 import java.util.UUID; 14  15 import com.train.ticket.Order; 16 import com.train.ticket.Ticket; 17 import com.train.ticket.Train; 18  19 public class CommonUtil { 20 //  /** 21 //   * 将对象转换为JSON字符串 22 //   *  23 //   * @param ob 24 //   * @return 25 //   */ 26 //  public static String toJSON(Object ob) { 27 //    try { 28 //      return JSONMarshaler.marshalObject(ob).toJSON(); 29 //    } catch (JSONMarshalerException e) { 30 //      return ""; 31 //    } 32 //  } 33  34   /** 35    * 生成Ticket信息 36    *  37    * @param train 38    * @return 39   */ 40   public static List<Ticket> initTicketList(Train train) { 41     List<Ticket> result = new ArrayList<Ticket>(); 42     Map<String, Integer> seatMap = train.getSeatTotalNum(); 43     for (Entry<String, Integer> entry : seatMap.entrySet()) { 44       int ticketSize = entry.getValue(); 45       String ticketType = entry.getKey(); 46       for (int i = 0; i < ticketSize; i++) { 47         int saleChannel = (int) (Math.random() * 10) % 8; 48         Ticket ticket = new Ticket(); 49         ticket.setSaleChannel(saleChannel); 50         ticket.setTicketType(ticketType); 51         ticket.setGuid(UUID.randomUUID().toString()); 52         ticket.setFromDate(train.getFromDate()); 53         ticket.setTicketFlag(CommonUtil.initTicketFlag(train)); 54         ticket.setTrainNo(train.getTrainNo()); 55         result.add(ticket); 56       } 57  58     } 59  60     return result; 61   } 62  63   /** 64    * 初始化票标记 65    *  66    * @param train 67    * @return 68   */ 69   public static String initTicketFlag(Train train) { 70     int stationNum = train.getStationNum(); 71     return new BigInteger("1").shiftLeft(stationNum - 1).toString(); 72   } 73  74   /** 75    * 生成购票站点 76    *  77    * @param j 78    * @return 79   */ 80   public static String buidTicket(int j) { 81     return new BigInteger("1").shiftLeft(j).toString(); 82   } 83  84   /** 85    * A方法追加文件:使用RandomAccessFile 86    * @param fileName 87    * @param content 88    * @param isConsule 89   */ 90   public static void appendMethodA(String fileName, String content, boolean isConsule) { 91      92     try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(fileName,true),"UTF-8");BufferedWriter bw = new BufferedWriter(out);){ 93       if(isConsule){ 94         System.out.println(content); 95         return; 96       } 97       bw.write(content); 98       bw.newLine(); 99       bw.flush();100       101     } catch (IOException e) {102       e.printStackTrace();103     }104   }105   /**106    * 107    * @param ticketStr108    * @param ticketList109    * @param train110    * @return111   */112   public static Map<String, Integer> getSeatLeftByticket(String ticketStr,113       List<Ticket> ticketList, Train train) {114     return null;115   }116   /**117    * 预订票票核心118    * 119    * @param ticketStr120    * @param ticketList121    * @param train122    * @return123   */124   public static List<Order> createOrderList(String ticketStr,125       List<Ticket> ticketList, Train train) {126     List<Order> tempListOrder = new ArrayList<Order>();127     Map<String, Integer> seatMap = train.getSeatTotalNum();128     for (Entry<String, Integer> entry : seatMap.entrySet()) {129       String ticketType = entry.getKey();130       Map p = new HashMap();131       p.put("ticketType", ticketType);132       boolean continues = true;133       int i= 0;134       while(continues){135         Order result = createOrderByCondition(ticketStr,ticketList,p);136         if(result!=null){137           tempListOrder.add(result);138           i++;139         } else {140           continues = false;141         }142         143       }144       //System.out.println("i"+i);145       146       147 148     }149     return tempListOrder;150   }151   /**152    * 根据筛选条件取得对应的车次153    * @param ticketStr154    * @param ticketList155    * @param condition156    * @return157   */158   159   public static Order createOrderByCondition(String ticketStr,List<Ticket> ticketList,Map condition){160     Order tempOrder = null;161     for (Ticket ticket : ticketList) {162 163       BigInteger toTicket = new BigInteger(ticketStr);164       BigInteger fromTicket = new BigInteger(ticket.getTicketFlag());165       // 如果可以订票,那么久进行扣除库存&&166       // (ticket.getSaleChannel()==(ticket.getSaleChannel()|1))167       if (canTicket(fromTicket, toTicket)168           &&ticket.getTicketType().equals(condition.get("ticketType").toString())169           //&&(ticket.getSaleChannel()==(ticket.getSaleChannel()|2))170           ) {171         tempOrder = new Order();172         tempOrder.setOrderId(UUID.randomUUID().toString());173         tempOrder.setSeatType(ticket.getTicketType());174         tempOrder.setTicketFlag(toTicket.toString());175         tempOrder.setTrainNO(ticket.getTrainNo());176         tempOrder.setFromDate(ticket.getFromDate());177         tempOrder.setSaleChannel(ticket.getSaleChannel());178         tempOrder.setTicketGuid(ticket.getGuid());179         ticket.setTicketFlag(fromTicket.or(toTicket).toString());180        break;181       } 182     }183     184     return tempOrder;185   }186 187   /**188    * 订票判断是否可以订票189    * 190    * @param fromTicket191    * @param toTicket192    * @return193   */194   private static boolean canTicket(BigInteger fromTicket, BigInteger toTicket) {195     return fromTicket.equals(fromTicket.not().or(toTicket).not());196   }197  /**198   * 创建199   * @param i200   * @param stationNum201   * @return202   */203   public static String buidTicket(int i, int stationNum) {204     BigInteger temp = new BigInteger("0");205     for (int j = i; j < stationNum; j++) {206       temp = temp.or(new BigInteger(buidTicket(j)));207     }208     return temp.shiftRight(1).toString();209   }210 }

View Code

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;//票据id11   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 }

View Code

3.票务实体

 1 package com.train.ticket; 2 /** 3  * 票务实体 4  * @author guo_zhifeng 5  * 6 */ 7 public class Ticket { 8   private String ticketFlag; 9   private String ticketType;10   private int saleChannel;11   private String trainNo;12   private String guid;13   private String fromDate;//发车日期14 15   public String getGuid() {16     return guid;17   }18 19   public void setGuid(String guid) {20     this.guid = guid;21   }22 23   public String getTrainNo() {24     return trainNo;25   }26 27   public void setTrainNo(String trainNo) {28     this.trainNo = trainNo;29   }30 31 32   public String getTicketFlag() {33     return ticketFlag;34   }35 36   public void setTicketFlag(String ticketFlag) {37     this.ticketFlag = ticketFlag;38   }39 40   public String getTicketType() {41     return ticketType;42   }43 44   public void setTicketType(String ticketType) {45     this.ticketType = ticketType;46   }47 48   public int getSaleChannel() {49     return saleChannel;50   }51 52   public void setSaleChannel(int saleChannel) {53     this.saleChannel = saleChannel;54   }55 56   public String getFromDate() {57     return fromDate;58   }59 60   public void setFromDate(String fromDate) {61     this.fromDate = fromDate;62   }63 64 }

View Code

4.列车初始化信息

 1 package com.train.ticket; 2  3 import java.util.Map; 4 /** 5  * 某一趟的列车的信息 6  * @author guo_zhifeng 7  * 8 */ 9 public class Train {10   private String trainNo;// 火车编号11   private int stationNum;// 车站数量12   private Map<String, Integer> seatTotalNum;// 各种座位的数量13   private String fromDate;14   15 16   public String getFromDate() {17     return fromDate;18   }19 20   public void setFromDate(String fromDate) {21     this.fromDate = fromDate;22   }23 24   public String getTrainNo() {25     return trainNo;26   }27 28   public void setTrainNo(String trainNo) {29     this.trainNo = trainNo;30   }31 32   public int getStationNum() {33     return stationNum;34   }35 36   public void setStationNum(int stationNum) {37     this.stationNum = stationNum;38   }39 40   public Map<String, Integer> getSeatTotalNum() {41     return seatTotalNum;42   }43 44   public void setSeatTotalNum(Map<String, Integer> seatTotalNum) {45     this.seatTotalNum = seatTotalNum;46   }47 48 }

View Code

5.主程序

 1 package com.train.main; 2  3 import java.io.File; 4 import java.math.BigDecimal; 5 import java.math.BigInteger; 6 import java.util.ArrayList; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map;10 11 import com.train.ticket.Order;12 import com.train.ticket.Ticket;13 import com.train.ticket.Train;14 import com.train.util.CommonUtil;15 16 public class MainTest {17 18   public static void main(String[] args) {19     Train train = new Train();20     train.setTrainNo("0909123SA873878");21     train.setFromDate("2016/06/11");22     train.setStationNum(18);23     Map<String, Integer> seatMap = new HashMap<String, Integer>();24     seatMap.put("商务座", 500);25     seatMap.put("一等座", 1000);26     seatMap.put("二等座", 2000);27     train.setSeatTotalNum(seatMap);28     // 生成票据29     System.out.println("初始化列车中的票");30     List<Ticket> ticketList = CommonUtil.initTicketList(train);31     String fileName = "D:\\RESULT.txt";32     File f = new File(fileName);33     if(f.exists()) f.delete();34     long startTime = System.currentTimeMillis();35     //int i = 0;36     //for (Ticket ticket : ticketList) {37     //  CommonUtil.appendMethodA(fileName,38     //      i + "||" + CommonUtil.toJSON(ticket) + "\n", true);39     //  i++;40     //}41     System.out.println("开始订票");42     long beginTime = System.currentTimeMillis();43     List<Order> orderResult = new ArrayList<Order>();44     45     for (int j = 0; j < train.getStationNum() - 1; j++) {46       String ticketStr = CommonUtil.buidTicket(j);47       //String ticketStr = CommonUtil.buidTicket(1,train.getStationNum());;48       //System.exit(0);49       50       List<Order> tempListOrder = CommonUtil.createOrderList(ticketStr,51           ticketList, train);52       orderResult.addAll(tempListOrder);53 54     }55     long endTime = System.currentTimeMillis();56     System.out.println("订票完成");57     //int m = 0;58 59 //    for (Ticket ticket : ticketList) {60 //      String temp = m + "||" + CommonUtil.toJSON(ticket) + ",";61 //      // System.out.println(temp);62 //      CommonUtil.appendMethodA(fileName, temp, true);63 //      m++;64 //    }65 //    int k = 1;66 //    for (Order order : orderResult) {67 //      String temp =   order.getOrderId() 68 //              + "||" + order.getSaleChannel() 69 //              + "||" + order.getFromDate() 70 //              + "||" + order.getSeatType() 71 //              + "||" + order.getTicketGuid()72 //              + "||" + order.getTrainNO() 73 //              + "||" + order.getTicketFlag()74 //              + "||" + new BigInteger(order.getTicketFlag()).toString(2)75 //              + "||" +k;76 //      CommonUtil.appendMethodA(fileName,temp, true);77 //      k++;78 //    }79     80     long eedTime = System.currentTimeMillis();81     System.out.println("生成订单" + orderResult.size() + "||耗时时间:"82         + (endTime - beginTime) + "毫秒");83     System.out.println("每秒钟生成单据数(逐张订票)"+ new BigDecimal(orderResult.size()).multiply(new BigDecimal(1000)).divide(new BigDecimal(endTime - beginTime),0,BigDecimal.ROUND_HALF_DOWN));84     85     System.out.println("执行完毕");86 87   }88 89 }

View Code

 6.运行结果

 源码工程: 源码

本文原创:转载请注明出处 http://www.cnblogs.com/feichengwurao/p/5202100.html