javascript模拟订火车票和退票示例


Posted in Javascript onApril 24, 2014

之前看到有人分析12306后台的逻辑。。火车票的预定和退订不同于普通的购物。
一个难题就是火车票可以分站来卖。比如,一张北京到上海的火车票,沿途可以有很多站,可以北京-济南,济南-南京...等等。如何设计数据模型来存取这些票是一个问题。而不是简单的数量+-1.

其中看到一条思路挺好:用二进制字符串来表示一张火车票,比如,北京到上海共10站,那么一张全程票初始状态表示为:'1111111111';
卖出一张全程票,则该票变为'0000000000';
卖出一张半程票,比如北京-济南三站(第一站-第三站),则票变为'0011111111';
再卖出一张半程票,比如徐州-南京(第6站-第9站),则上一张票变为:'0011100011';

退订票的逻辑就很简单了,我要退一张(徐州-南京)的票,则从票池中找到第一张不能买
(徐州-南京)的票,更改它就OK(买票的逆向).比如,找到了上面的一张票'0011100011',
退票后,此票变为(0011111111);

基本逻辑如上,12306要保证多入口,而同时数据的一致性,需要很高效的逻辑来处理查票,
买票,退票的业务,据说高峰每秒会有20万请求。将票的数据结构保存在内存中。而非数据库。
小而高效的数据结变得很重要。

if(jQuery){}else{
 //document.write
}
function Server(){
 var self = this;
 self.ticketsPool = [];
 self._init= function(number){
  if(typeof(number) != 'number')
   throw ('type error');
  for(i=0;i<number;i++){
   self.ticketsPool.push(new Ticket());
  }
 };
 //判断一张票是否可以买,通过与或运算来实现。
 //比如:订单o为北京-济南(001111111),某张票为(0000000011)(已卖出北京-南京),那么返回false
 //比如:订单o为北京-济南(001111111),某张票为(1111100011)(已卖出徐州-南京),那么返回true
 self.canBuy = function(o,t){
  var _o = ''
  for(j=0; j<o.length; j++){
   _o += o[j]=='0'?1:0;
  }
  var r1 = (parseInt(t.tic,2) | parseInt(o,2)) & parseInt(_o,2);
  var r2 = parseInt(_o,2);
  return r1 == r2;
 };
 //卖出一张票
 self.pop1Ticket = function(o){
   for(i=0;i < self.ticketsPool.length;i++){
    if(self.canBuy(o,self.ticketsPool[i])){
     self.buy(self.ticketsPool[i],o);
     return i;
   }
  };
  return -1;
 };
 //卖出票的实现,改变二进制字符串,比如'111111111'->'001111111';
 self.buy = function(t,o){
  t.tic = (parseInt(t.tic,2) & parseInt(o,2)).toString(2);
  //alert(t.tic);
 };
 //查询余票
 self.remainTics = function(o){
   var count=0;
   for(i=0;i < self.ticketsPool.length;i++){
    count += self.canBuy(o,self.ticketsPool[i])?1:0;
  };
  return count;
 }
 //退票,或 运算
 self.refund = function(o){
   for(i=0;i < self.ticketsPool.length;i++){
    if(!self.canBuy(o,self.ticketsPool[i])){
     var _o = ''
     for(j=0; j<o.length; j++){
      _o += o[j]=='0'?1:0;
     }
     self.ticketsPool[i].tic = (parseInt(self.ticketsPool[i].tic,2) | parseInt(_o,2)).toString(2);
     return i;
   } 
  };
  return -1;
 }
}
//数据模型:票
function Ticket(){
 var self = this;
 //票的初始为全程票
 self.tic = '1111111111';
}
//数据模型:订单
function Order(from, to){
 var self = this;
 var s = '';
 for(i=0;i<10;i++){
  s += (i>=from && i<to)?0:1;
 }
 return s;
}
//12306后台
Server = new Server();
//初始状态,票池有400张全程票
Server._init(400);
Javascript 相关文章推荐
Jquery下EasyUI组件中的DataGrid结果集清空方法
Jan 06 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
Mar 03 Javascript
AngularJS语法详解(续)
Jan 23 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
Jun 03 Javascript
原生js实现自由拖拽弹窗代码demo
Jun 29 Javascript
js中常用的Tab切换效果(推荐)
Aug 30 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
Jun 13 Javascript
使用vue实现grid-layout功能实例代码
Jan 05 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
Apr 20 Javascript
Vue函数式组件的应用实例详解
Aug 30 Javascript
layui表格设计以及数据初始化详解
Oct 26 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 #Javascript
jquery map方法使用示例
Apr 23 #Javascript
js通过更改按钮的显示样式实现按钮的滑动效果
Apr 23 #Javascript
js Dialog 去掉右上角的X关闭功能
Apr 23 #Javascript
Jquery实现Div上下移动示例
Apr 23 #Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
Apr 23 #Javascript
JQuery下拉框应用示例介绍
Apr 23 #Javascript
You might like
十天学会php之第四天
2006/10/09 PHP
PHP使用PHPexcel导入导出数据的方法
2015/11/14 PHP
JSON两种结构之对象和数组的理解
2016/07/19 PHP
yii2-GridView在开发中常用的功能及技巧总结
2017/01/07 PHP
PHP单例模式模拟Java Bean实现方法示例
2018/12/07 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
js下判断 iframe 是否加载完成的完美方法
2010/10/26 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
2013/07/05 Javascript
Javascript 浮点运算的问题分析与解决方法
2013/08/27 Javascript
jquery统计输入文字的个数并对其进行判断
2014/01/07 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
2015/10/26 Javascript
Bootstrap每天必学之警告框插件
2016/04/26 Javascript
JavaScript中instanceof运算符的使用示例
2016/06/08 Javascript
谈谈第三方App接入微信登录 解读
2016/12/27 Javascript
JavaScript中for循环的几种写法与效率总结
2017/02/03 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
原生JS仿QQ阅读点击展开、收起效果
2017/03/08 Javascript
深入解析Vue 组件命名那些事
2017/07/18 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
2017/10/26 Javascript
使用classList来实现两个按钮样式的切换方法
2018/01/24 Javascript
angular的输入和输出的使用方法
2018/09/22 Javascript
Layui 动态禁止select下拉的例子
2019/09/03 Javascript
jquery中attr、prop、data区别与用法分析
2019/09/25 jQuery
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
详细分析vue响应式原理
2020/06/22 Javascript
Django读取Mysql数据并显示在前端的实例
2018/05/27 Python
python pandas修改列属性的方法详解
2018/06/09 Python
python之线程通过信号pyqtSignal刷新ui的方法
2019/01/11 Python
python 爬取疫情数据的源码
2020/02/09 Python
Pycharm最常用的快捷键及使用技巧
2020/03/05 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
党员岗位承诺口号大全
2014/03/28 职场文书
财务出纳岗位职责
2015/03/31 职场文书
小学英语教师研修感悟
2015/11/18 职场文书
Python基础知识学习之类的继承
2021/05/31 Python
Matplotlib绘制条形图的方法你知道吗
2022/03/21 Python