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 相关文章推荐
extjs grid设置某列背景颜色和字体颜色的方法
Sep 03 Javascript
input禁止键盘及中文输入,但可以点击
Feb 13 Javascript
jQuery随机密码生成的方法
Mar 09 Javascript
深入理解setTimeout函数和setInterval函数
May 20 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
Feb 05 Javascript
jquery dialog获取焦点的方法
Feb 09 Javascript
Vue 进阶教程之v-model详解
May 06 Javascript
微信小程序日历组件calendar详解及实例
Jun 08 Javascript
原JS实现banner图的常用功能
Jun 12 Javascript
vue.js轮播图组件使用方法详解
Jul 03 Javascript
JavaScript实现打砖块游戏
Feb 25 Javascript
在Vue中使用mockjs代码实例
Nov 25 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
关于初学PHP时的知识积累总结
2013/06/07 PHP
php使用fgetcsv读取csv文件出现乱码的解决方法
2014/11/08 PHP
php生成txt文件实例代码介绍
2016/04/28 PHP
PHP使用内置函数生成图片的方法详解
2016/05/09 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
2019/09/04 PHP
jquery $(document).ready() 与window.onload的区别
2009/12/28 Javascript
读jQuery之十二 删除事件核心方法
2011/07/31 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
node.js中实现同步操作的3种实现方法
2014/12/05 Javascript
Eclipse引入jquery报错如何解决
2015/12/01 Javascript
原生JavaScript实现动态省市县三级联动下拉框菜单实例代码
2016/02/03 Javascript
倾力总结40条常见的移动端Web页面问题解决方案
2016/05/24 Javascript
javascript入门之window对象【新手必看】
2016/11/22 Javascript
vue遍历对象中的数组取值示例
2019/11/07 Javascript
Node.js API详解之 os模块用法实例分析
2020/05/06 Javascript
详细分析React 表单与事件
2020/07/08 Javascript
python分割文件的常用方法
2014/11/01 Python
python保存数据到本地文件的方法
2018/06/23 Python
详解Python with/as使用说明
2018/12/13 Python
python之验证码生成(gvcode与captcha)
2019/01/02 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
pow在python中的含义及用法
2019/07/11 Python
在python中求分布函数相关的包实例
2020/04/15 Python
python 读取二进制 显示图片案例
2020/04/24 Python
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
介绍一下javax.servlet.Servlet接口及其主要方法
2015/11/30 面试题
英语专业大学生求职简历的自我评价
2013/10/18 职场文书
公务员保密承诺书
2014/03/27 职场文书
优秀班主任事迹材料
2014/12/16 职场文书
情人节活动总结范文
2015/02/05 职场文书
小学数学国培研修日志
2015/11/13 职场文书
小学四年级作文之写景
2019/08/23 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
MySQL 重写查询语句的三种策略
2021/05/10 MySQL
如何用vue实现网页截图你知道吗
2021/11/17 Vue.js