火车票余票问题的算法解析(续)

作者: Phill King

邮箱: phillking1982@163.com

原创文章,转载请注明出处。

在之前的文章中,我分析了火车票余票的问题,提供了一个高效的算法。在本文中,我们继续讨论无座位号的余票计算以及逐票更新的问题。  之前的分析参见: https://blog.csdn.net/jinij/article/details/87971283 

无座位号余票计算

还是以站点数=6, 座位=5为例

如果不考虑座位号,我们只需要考虑每站售出的票数即可。

(1-2)的余票数即为 总票数减去售票数 5 - 2 = 3

(2-3)的余票数即为 总票数减去售票数 5 - 3= 2

以此类推

(1-3)的余票数即为 总票数减去 (1-2)和(2-3)售票数较大者   即  5- max(2,3) = 2

(2-4)的余票数即为 总票数减去 (2-3)和(3-4)售票数较大者   即  5- max(3,4) = 1

以此类推

计算余票的公式

设定 Ti 代表从i站到i+1站的售票数, 如T1 = 2, T2=3

以T(i,j)表示从 i站到j站的售票数

T(i,j) = 总票数  -  max(Ti, Ti+1, ... Tj-1)

同理,如果用Ri代表从i站到i+1站的余票数

以R(i,j)表示从 i站到j站的售票数

R(i,j)  = min(Ri, Ri+1, ... Rj-1)

对应的余票表:

只需要计算和保存每个站点段的余票数,就可以更新任意两个站点的余票数或整张余票表。

由此可以看出无座位号的余票计算方式更简单更快。

逐票更新

如果想要每购买一张票之后就更新余票表,即无需更新整张表,而只需更新受到影响的部分站点。

无座位号逐票更新

我们看一下无座位号逐票更新的例子。(行表头是起点站, 列表头是到达站)

假设每站总票数为10,现在购买了3-4站的一张车票,那么更新的范围是其右上方的矩形。

影响的范围对于(i,i+1)站段来说是:  行从0到i, 列从i+1到终点站的矩形范围。

如果再购买一张4-5的票,新的余票表如下:

在更新余票的时候我们逐个比较余票的值,

如果余票本来的值比新的值大,则更新为新的值;

如果余票本来的值已经小于新的值,则无需更新。

以购买一张3-4站,然后购买一张3-5站为例

 

有座位号的逐票更新

有座位号的逐票更新余票逻辑相对简单,只需要把更新范围内的集合都更新一遍即可。

以购买一张3-4站车票为例:

将影响范围内的集合都更新一遍,如果该座位已被包含,可以跳过之后的座位更新。(具体细节不做累述)

同样采用位图法,可以获得很好的性能。

 

总结

本文对火车票余票问题的无座位号余票更新和逐票更新的情况做了详细的分析。

逐票更新的性能超过更新整张表,但是如果对每张票都做更新总体上需要消耗更多的资源和时间。

具体要视实际需求而定。

相关的代码可以在之前的文章内找到

火车票余票问题的算法分析

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值