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 相关文章推荐
你必须知道的Javascript知识点之&quot;单线程事件驱动&quot;的使用
Apr 23 Javascript
JS无限极树形菜单,json格式、数组格式通用示例
Jul 30 Javascript
input禁止键盘及中文输入,但可以点击
Feb 13 Javascript
js中匿名函数的创建与调用方法分析
Dec 19 Javascript
javascript实现在下拉列表中显示多级树形菜单的方法
Aug 12 Javascript
js实现仿爱微网两级导航菜单效果代码
Aug 31 Javascript
Javascript中document.referrer隐藏来源的方法
Jan 16 Javascript
echarts学习笔记之箱线图的分析与绘制详解
Nov 22 Javascript
详解javascript 正则表达式之分组与前瞻匹配
May 30 Javascript
vue中Axios的封装与API接口的管理详解
Aug 09 Javascript
VScode格式化ESlint方法(最全最好用方法)
Sep 10 Javascript
Vue js with语句原理及用法解析
Sep 03 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和XSL stylesheets转换XML文档
2006/10/09 PHP
php class类的用法详细总结
2013/10/17 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
解决Laravel自定义类引入和命名空间的问题
2019/10/15 PHP
jquery 实现的全选和反选
2009/04/15 Javascript
node.js中的buffer.toString方法使用说明
2014/12/14 Javascript
JavaScript函数的一些注意要点小结及js匿名函数
2015/11/10 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
JS+html5 canvas实现的简单绘制折线图效果示例
2017/03/13 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
vue绑定事件后获取绑定事件中的this方法
2018/09/15 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
js实现简单音乐播放器
2020/06/30 Javascript
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
Python中用altzone()方法处理时区的教程
2015/05/22 Python
Python中functools模块的常用函数解析
2016/06/30 Python
Python实现小数转化为百分数的格式化输出方法示例
2017/09/20 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
Python发送邮件测试报告操作实例详解
2018/12/08 Python
selenium+python自动化测试之使用webdriver操作浏览器的方法
2019/01/23 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
Python暴力破解Mysql数据的示例
2020/11/09 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
2021/03/04 Python
详解canvas drawImage()方法绘制图片不显示的问题
2018/10/08 HTML / CSS
经理管理专业自荐信范文
2013/12/31 职场文书
高一历史教学反思
2014/01/13 职场文书
红色故事演讲稿
2014/05/22 职场文书
全国文明单位申报材料
2014/05/31 职场文书
2014年绿化工作总结
2014/12/09 职场文书
世界文化遗产导游词
2015/02/13 职场文书
赢在中国观后感
2015/06/02 职场文书
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL
Python中的协程(Coroutine)操作模块(greenlet、gevent)
2022/05/30 Python