空座位
有一个能容纳 1000 人的餐馆,他们将座位按顺序编号并记录在了数据库表中,每个客人就坐之后,服务员就会在座位表中标记一下,当客人离开后,就删除这个标记。某一时刻下的该表如下:
由于经常有客人是多位一起,需要坐到连续的座位上,为方便寻找这种连续的座位,餐馆需要一个同步的“空闲座位片区表”,用于记录当前的空闲座位有哪些区段,以及每个区段的位置。
请帮助餐馆的管理员,由上面的座位表生成空闲座位片区表。
合并相同的内容,集算器中的分组函数可以解决,而只合并相邻的相同内容,group 函数带有不排序参数可选,使用@o选项不排序分组就可以完美的解决这个问题。
A |
|
1 |
=T("Seatings.txt") |
2 |
=A1.group@o(Availability;~.count():NumberOfSeats,~.SeatNo:StartingSeatNo) |
3 |
=A2.select(Availability) |
https://try.esproc.com/splx?4nr
A1读取座位表。
A2按是否有客人进行不排序分组,统计每段连续有人或无人的座位数,以及起始座号:
A3从中选出空座位的选取结果:
实际情况下的空座位问题会比上面的例子复杂很多,座位会有很多排,也并不会有1000个连排座位的情况,下面再看一个更复杂的空座位问题。
一个电影院的某个放映厅座位表如下:
放映厅中座位被两排通道隔为3个区域,绿色为空座位,红色为已占用座位。现在需要统计出每段空座位的连续个数以及起始位置,位置用行号-列号表示,如3-12表示第3排第12个座位。
先用序列表示座位情况,每排座位用一串字符,空座位用O表示,已占用座位用X表示,通道用P表示。然后循环每一排座位,类似前面题目的处理,不排序分组统计每段连续座位的总数和起始座位号,由于存在通道占位,因此计算起始座位号时需要先得到每个位置对应的号码。最后选出空座位的结果,并将各排的结果合并在一起即可。
A |
|
1 |
OOOOOOPOOOOOOOOOOOOPOOOOOO |
2 |
OOOOOOPOOOOOXXOOOOOPOOOOOO |
3 |
OOOOOOOPOOOXXXXXXXOOPOOOOOOO |
4 |
OXXOOOOOPOOOOOOOOOOOOPOXXOOOOO |
5 |
OOOOOXXOOPOOOOXXXXXXXOPOOOOOXXOO |
6 |
OOOXXXXXXXPOOOOOXOOOOOOPOOOXXXXXXX |
7 |
OOOOOXXOOOPOOOXXXXOXXOOPOOOOOOXXOO |
8 |
OOOOOOOOOOPOOOOOOOXXXXOPOOOOOOOOOO |
9 |
OOOOOOOOOOPOOOOOXXXXXOOPOOOOOOOOOO |
10 |
OOOOOOOOOOPOOOOOOOOOOOOPOOOOOOOOOO |
11 |
OOOOOXXXXXPOOOXXOOOOOOOPOOOOOOXXXX |
12 |
OOOOOOOXXOPOOOOOOOOOOOOPOOOOOOOOOX |
13 |
=[A1:A12].(~.split()) |
14 |
=A13.(a=0,~.(if(~=="P",0,a+=1))) |
15 |
=A13.(r=#,rn=A14(#),~.groups@o(~:Status;count(~):NumberOfSeats, r/"-"/rn(#):StartingSeatNo)) |
16 |
=A15.(~.select(Status=="O")).conj() |
https://try.esproc.com/splx?4DR
前12行根据座位示意图记录座位占用情况,O代表空座位,X代表已占用座位,P表示通道占位。
A13将每行座位按字符逐个拆分为序列如下,A14计算每排中各个位置的座位号,通道位置设为0:
A15循环每一行,按座位状态进行不排序分组,统计每段连续有人或无人的座位数,以及起始座号,起始座位号由行号和从A14中获得的座位号组成:
A16选出每行的空座位记录,并用conj将各行结果合并:
跟着练习一下…groups@0 丢弃一参为 null 的分组,座位计数编号写进一参
Seatings.txt
英文版