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实现的DES加密示例
Oct 30 Javascript
JS随机漂浮广告代码具体实例
Nov 19 Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 Javascript
js文本框输入内容智能提示效果
Dec 02 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
Jun 01 Javascript
BootStrap树状图显示功能
Nov 24 Javascript
Vue.js组件tree实现无限级树形菜单
Dec 02 Javascript
微信小程序富文本渲染引擎的详解
Sep 30 Javascript
解决Vue2.0 watch对象属性变化监听不到的问题
Sep 11 Javascript
详解Vue中数组和对象更改后视图不刷新的问题
Sep 21 Javascript
vue 组件销毁并重置的实现
Jan 13 Javascript
详解Vue的七种传值方式
Feb 08 Vue.js
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
如何限制访问者的ip(PHPBB的代码)
2006/10/09 PHP
UCenter中的一个可逆加密函数authcode函数代码
2010/07/20 PHP
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
PHP实现可添加水印与生成缩略图的图片处理工具类
2018/01/16 PHP
js查找父节点的简单方法
2008/06/28 Javascript
JS获取整个页面文档的实现代码
2011/12/15 Javascript
关于火狐(firefox)及ie下event获取的两种方法
2012/12/27 Javascript
js作用域及作用域链概念理解及使用
2013/04/15 Javascript
拖动table标题实现改变td的大小(css+js代码)
2013/04/16 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
js使用ajax读博客rss示例
2014/05/06 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
js中的caller和callee属性介绍和例子
2014/06/07 Javascript
seajs学习教程之基础篇
2016/10/20 Javascript
JS实现太极旋转思路分析
2016/12/09 Javascript
node.js调用Chrome浏览器打开链接地址的方法
2017/05/17 Javascript
微信小程序实现购物页面左右联动
2019/02/15 Javascript
详解vue中router-link标签所必备了解的属性
2019/04/15 Javascript
js调用网络摄像头的方法
2020/12/05 Javascript
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
Windows下安装python2和python3多版本教程
2017/03/30 Python
浅谈Pandas中map, applymap and apply的区别
2018/04/10 Python
Python基于opencv的图像压缩算法实例分析
2018/05/03 Python
matplotlib绘制鼠标的十字光标的实现(内置方式)
2021/01/06 Python
捷克电器和DJ设备网上商店:Electronic-star
2017/07/18 全球购物
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
中海讯通笔试题
2015/09/15 面试题
常用UNIX 命令(Linux的常用命令)
2013/07/10 面试题
DOM和JQuery对象有什么区别
2016/11/11 面试题
优秀士兵先进事迹
2014/02/06 职场文书
最新大学生创业计划书写作攻略
2014/04/02 职场文书
股东协议书
2014/04/14 职场文书
拖欠货款起诉状
2015/05/20 职场文书
客户答谢会致辞
2015/07/30 职场文书
家长会感言
2015/08/01 职场文书