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 相关文章推荐
div模拟滚动条效果示例代码
Oct 16 Javascript
js实现文本框中焦点在最后位置
Mar 04 Javascript
JavaScript数值千分位格式化的两种简单实现方法
Aug 01 Javascript
JS求解三元一次方程组值的方法
Jan 03 Javascript
js实现单张图片平移切换效果
Oct 11 Javascript
浅谈Node Inspector 代理实现
Oct 19 Javascript
vuex 解决报错this.$store.commit is not a function的方法
Dec 17 Javascript
详解vue-cli3 中跨域解决方案
Apr 10 Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 Javascript
Vue最新防抖方案(必看篇)
Oct 30 Javascript
jQuery操作事件完整实例分析
Jan 10 jQuery
javaScript Array api梳理
Mar 31 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&amp;&amp;mysql)六
2006/10/09 PHP
php使用cookie显示用户上次访问网站日期的方法
2015/01/26 PHP
Javascript - HTML的request类
2007/01/09 Javascript
JavaScript 学习笔记(十三)Dom创建表格
2010/01/21 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
Javascript数组与字典用法分析
2014/12/13 Javascript
JavaScript学习笔记之数组的增、删、改、查
2016/03/23 Javascript
js内置对象处理_打印学生成绩单的简单实现
2016/09/24 Javascript
jquery实现(textarea)placeholder自动换行
2016/12/22 Javascript
详解AngularJS ui-sref的简单使用
2017/04/24 Javascript
在Js页面通过POST传递参数跳转到新页面详解
2017/08/25 Javascript
React教程之Props验证的具体用法(Props Validation)
2017/09/04 Javascript
Vue组件中的data必须是一个function的原因浅析
2018/09/03 Javascript
关于单文件组件.vue的使用
2018/09/20 Javascript
js+html实现周岁年龄计算器
2019/06/25 Javascript
JavaScript观察者模式原理与用法实例详解
2020/03/10 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
2020/09/01 Javascript
Vue-Ant Design Vue-普通及自定义校验实例
2020/10/24 Javascript
Vue——解决报错 Computed property &quot;****&quot; was assigned to but it has no setter.
2020/12/19 Vue.js
python3.5 email实现发送邮件功能
2018/05/22 Python
解决python tkinter界面卡死的问题
2019/07/17 Python
PyCharm中代码字体大小调整方法
2019/07/29 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
来自南加州灵感的工作和娱乐服装:TravisMathew
2019/05/01 全球购物
英国珠宝和手表专家:Pleasance & Harper
2020/10/21 全球购物
介绍一下HTTP、HTTPS和SSL
2012/12/16 面试题
舞蹈教育学专业推荐信
2013/11/27 职场文书
银行实习鉴定
2013/12/13 职场文书
20年同学聚会感言
2014/02/03 职场文书
2014年人力资源部工作总结
2014/11/19 职场文书
邀请函怎么写
2015/01/30 职场文书
销售工作决心书
2015/02/04 职场文书
幼儿园语言教学反思
2016/02/23 职场文书
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
redis中lua脚本使用教程
2021/11/01 Redis
基于Python实现西西成语接龙小助手
2022/08/05 Golang