javascript模拟订火车票和退票示例


之前看到有人分析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);



相关阅读:
浅析node.js中close事件
设计适用于打印的CSS样式
Mongodb聚合函数count、distinct、group如何实现数据聚合操作
jQuery对checkbox 复选框的全选全不选反选的操作
mysql 复制过滤重复如何解决
Android实现可浏览和搜索的联系人列表
C#使用系统方法发送异步邮件完整实例
MYSQL必知必会读书笔记第七章之数据过滤
android 引导界面的实现方法
java中的自增问题介绍
使用JS获取当前地理位置方法汇总
js分页代码分享
SQLite学习手册(SQLite在线备份)
Android解决dialog弹出时无法捕捉Activity的back事件的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 市政府春节慰问信 小班语言活动教案:不挑食 成长中的烦恼小学生作文300字 人为什么总是会伤害最爱你的人? 语言的调性基本决定一个人八成以上的性格特征 请给我指下方向 谢恩:低薪制会诱导腐败算不算高级黑 经济局“感恩思进”活动第一阶段工作小结 我们是否需要太空探索(DoWeNeedSpaceExploration) 乡镇贯彻全市统战工作会议精神情况汇报 在全市纪检监察干部会议上的讲话 借你东风吹花落 最新妇女节搞笑祝福语短信 民事判决书(撤销有关民事行为能力的宣告用) 小学生周记 一年级语文老师个人工作总结 人这一生,就是彼此寻找安慰 春节作文1000字:我回家乡过春节 爱你不需要理由作文900字 凡人善举 关于我的家庭作文400字 20年以后的我们 军训通讯稿范文三篇 建筑施工工程师工作总结 2016婚庆公司开业庆典主持词 个人工作证明范本 庆祝建国60周年演讲稿:祖国在我们心中2篇 心痛、残泪。 赶海作文1600字 奢华迪拜---最奢华的酒店.帆船酒店 我的老师们作文2000字 那片阳光美得那么动人 Hello,夜先生 梦在水星 在我们离婚前希望你能看到 小学五年级作文900字:我眼中的新上海 2010年在学校教职工代表大会上的讲话 上班族如何理财 闲时所作 某县电力改革开放30周年征文 2012年度水路运输行业年审工作总结 2017年度工作计划范文 为了忘却的纪念作文1000字 副市长在全市防震减灾工作会议上的讲话 《短篇小说选读》阶段性综合检测(一) 对乔布斯的评价 《没有任何借口》读后感2 文章爱情伤感语录摘抄 做一个勇敢的少年——读爱的教育有感 春终于来了

Copyright © 2016 phpStudy |