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语言中的Literal Syntax特性分析
Mar 08 Javascript
javascript之函数直接量(function(){})()
Jun 29 Javascript
基于jquery的文章中所有图片width大小批量设置方法
Aug 01 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
Jun 10 Javascript
纯JavaScript实现的分页插件实例
Jul 14 Javascript
node.js缺少mysql模块运行报错的解决方法
Nov 13 Javascript
微信小程序 欢迎界面开发的实例详解
Nov 30 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
前端主流框架vue学习笔记第一篇
Jul 26 Javascript
JavaScript继承与聚合实例详解
Jan 22 Javascript
新手快速入门微信小程序组件库 iView Weapp
Jun 24 Javascript
elementUI 动态生成几行几列的方法示例
Jul 11 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基础陷阱题(变量赋值)
2012/09/12 PHP
PHP实现简单爬虫的方法
2015/07/29 PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
2016/10/29 PHP
详谈php ip2long 出现负数的原因及解决方法
2017/04/05 PHP
php判断str字符串是否是xml格式数据的方法示例
2017/07/26 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
2018/04/21 PHP
php中数组最简单的使用方法
2020/12/27 PHP
基于jquery的商品展示放大镜
2010/08/07 Javascript
jquery.pagination.js 无刷新分页实现步骤分享
2012/05/23 Javascript
jQuery中(function($){})(jQuery)详解
2015/07/15 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
2017/03/08 Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
2017/05/08 Javascript
Vue.js 中的 $watch使用方法
2017/05/25 Javascript
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
vue自定义指令之面板拖拽的实现
2019/04/14 Javascript
vscode+gulp轻松开发小程序的完整步骤
2020/10/18 Javascript
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
Python自动化测试ConfigParser模块读写配置文件
2016/08/15 Python
好的Python培训机构应该具备哪些条件
2018/05/23 Python
python dict 相同key 合并value的实例
2019/01/21 Python
python无序链表删除重复项的方法
2020/01/17 Python
利用keras加载训练好的.H5文件,并实现预测图片
2020/01/24 Python
对Python 字典元素进行删除的方法
2020/07/31 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
学习雷锋活动总结
2014/04/29 职场文书
行政部经理助理岗位职责
2014/06/15 职场文书
处级领导干部四风问题自我剖析材料
2014/09/29 职场文书
跳高加油稿
2015/07/21 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
vue引入Excel表格插件的方法
2021/04/28 Vue.js
python生成可执行exe控制Microsip自动填写号码并拨打功能
2021/06/21 Python
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android