第五次作业指导书


第五次作业指导书

第一部分:训练目标

学习正则表达式捕获组和模糊匹配,非贪婪匹配等知识,并依此实现更加高级的检索功能。


第二部分:预备知识

本次作业的完成可能需要用到的知识如下。

捕获组

  • 关于正则表达式的捕获:当我们想要获取正则表达式里的某些指定的内容时,可以利用捕获组来进行操作,通过group()方法捕获想要的内容。

详细内容可以参考

贪婪匹配和非贪婪匹配

  • 关于模糊匹配和非贪婪匹配模式:对于表达式中间可能出现的无关紧要的部分,我们通常采用模糊匹配来进行处理。同时,由于性能原因,我们建议大家使用非贪婪模式进行匹配。

    我们通常使用.*?来表示非贪婪模式,其中.表示任意字符,*?表示重复任意次,但尽可能少重复。顾名思义,非贪婪模式就是在能使整个匹配成功的前提下匹配最少的字符,比如如果将a.*?b应用在aabab中,我们匹配到的会是aabab

  • 关于非贪婪匹配模式还有一些其他表示方式可供参考:

代码 说明
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

相关详细内容可以参考 参考资料1 参考资料2


第三部分:基本概念

概念 定义
子序列 将字符串中零个或多个字符去掉后所得结果,一个字符串 abc 的子序列有 a, b, c, ab, ac, bc, abc
子串 字符串中任意个连续的字符组成的子序列
前缀 包含第0个字符的子串
后缀 包含最后一个字符的子串

第四部分:题目描述

形式化来说,消息可能被表现成以下三种模式:

  • 给个人的消息:yyyy/MM/dd-sender@receiver :"message_content";

    2021/07/12-student@teacher :"can i pass the exam?";

    本消息为发送给个人的消息,指定了接收者teacher。

  • 群聊中的消息,指定了接收者:yyyy/MM/dd-sender:"message_content";,其中message_content内包含@receiver

    2021/07/12-student:"can i pass the exam?@teacher ";

    本消息为在群聊中发送的消息,指定了接收者teacher。

  • 群聊中的消息,未指定接收者:yyyy/MM/dd-sender:"message_content";

    2021/07/12-student:"can i pass the exam?";

    本消息为在群聊中发送的消息,未指定接收者。

有些用户喜欢在群聊或聊天中使用昵称,比如名为 “小枫”的用户可以有昵称 “小小枫”、“小枫枫”。

用户名或备注的前缀或后缀可能含有一些特殊含义,比如“2006 张一一”、“2006 刘一一”、“王一一 19级”、“陈一一 20级”,其中的数字代表着年,隐含着当年入学或入职等信息。

在查询时,我们同样不可能每次都能精准地记得所需消息的日期,接收方以及发送方的姓名,因此在这里我们需要实现模糊查询的功能。

请编写程序读入消息,并根据输入的查询找出对应的消息。

查询指令将在原有基础上作如下调整。

  • qdate指令输入的日期可能不是完整的日期,具体地,所有可能的日期格式有yyyy/MM/dd, yyyy/MM/, yyyy//dd, /MM/dd, //dd, /MM/, yyyy//,你需要输出所有符合输入日期的消息。例如若输入qdate /07/03,则你需要输出所有在07/03发布的消息,无论消息在哪一年发出。其余格式同理。
  • qsendqrecv将加入参数-v表示模糊搜索,类似于我们的命令行,当输入qsend -vqrecv -v时表示对后面输入的内容进行模糊搜索,该次作业中,我们规定,输入 qsend -v "str"qrecv -v "str",表示检索以str为子串的名称,具体详见样例。当-v缺省时表示含义与第一次作业相同,即”精确匹配“。

第五部分:输入/输出说明

输入格式

前若干行为消息内容,以一行END_OF_MESSAGE结尾。其中一行内可能有多条消息,每条消息之间和每行末尾可能存在若干空白字符(空格和制表符\t)。

其后为多条查询语句,每行一条。

查询指令有且仅有qdate,qrecv,qsend,格式参照上述。

输出格式

对于每一条询问,输出指定消息(输入数据中可能存在多条消息符合条件,此时按照原顺序、原格式输出全部符合条件的消息)。

输出中每条消息均单独占据一行。

输入样例1

2021/7/1-Jack@JayChou :"Hello! mydear.";2021/7/3-JayChou@buaaer :"nice to meet you.";
2021/7/5-JayChou@Mike :"emmmm..., I am sorry.";
2021/7/6-JayChou@Mike :"emmmm..., I do not want to talk to you.";         2020/7/8-JayChou@buaaer :"Hahaha! see you again";
2020/7/8-JayChou@Sabbaty :"Hahaha! Sabbaty, come to the center!";
2021/6/8-JayChou:"I am JayChou!";
2021/7/11-JayChou:"I love you!";
2021/1/1-JayChou:"Hi@c ";
END_OF_MESSAGE
qsend "Jack"
qsend -v "Ja"
qrecv "buaaer"
qrecv -v "e"

输出样例1

2021/7/1-Jack@JayChou :"Hello! mydear.";
2021/7/1-Jack@JayChou :"Hello! mydear.";
2021/7/3-JayChou@buaaer :"nice to meet you.";
2021/7/5-JayChou@Mike :"emmmm..., I am sorry.";
2021/7/6-JayChou@Mike :"emmmm..., I do not want to talk to you.";         
2020/7/8-JayChou@buaaer :"Hahaha! see you again";
2020/7/8-JayChou@Sabbaty :"Hahaha! Sabbaty, come to the center!";
2021/6/8-JayChou:"I am JayChou!";
2021/7/11-JayChou:"I love you!";
2021/1/1-JayChou:"Hi@c ";
2021/7/3-JayChou@buaaer :"nice to meet you.";
2020/7/8-JayChou@buaaer :"Hahaha! see you again";
2021/7/3-JayChou@buaaer :"nice to meet you.";
2021/7/5-JayChou@Mike :"emmmm..., I am sorry.";
2021/7/6-JayChou@Mike :"emmmm..., I do not want to talk to you."; 
2020/7/8-JayChou@buaaer :"Hahaha! see you again";

输入样例2

2021/7/1-Jack@JayChou :"Hello!";2021/7/3-JayChou@buaaer :"Hahaha";
2021/7/5-JayChou@Mike :"emmmm";         2020/7/8-JayChou@buaaer :"Hahaha";
2021/6/8-JayChou:"Hahaha";
END_OF_MESSAGE
qdate 2021/7/1
qdate 2021//
qdate /7/
qdate //1
qdate 2021/7/
qdate /7/1

输出样例2

2021/7/1-Jack@JayChou :"Hello!";
2021/7/1-Jack@JayChou :"Hello!";
2021/7/3-JayChou@buaaer :"Hahaha";
2021/7/5-JayChou@Mike :"emmmm";
2021/6/8-JayChou:"Hahaha";
2021/7/1-Jack@JayChou :"Hello!";
2021/7/3-JayChou@buaaer :"Hahaha";
2021/7/5-JayChou@Mike :"emmmm";
2020/7/8-JayChou@buaaer :"Hahaha";
2021/7/1-Jack@JayChou :"Hello!";
2021/7/1-Jack@JayChou :"Hello!";
2021/7/3-JayChou@buaaer :"Hahaha";
2021/7/5-JayChou@Mike :"emmmm"; 
2021/7/1-Jack@JayChou :"Hello!";

输入样例3

2022/07/04-Jack:"I have a leading zero.";
2022/7/4-Jack:"I dont have leading zero";
2022/7/04-Jack:"We have the same meaning!";
END_OF_MESSAGE
qdate 2022//4
qdate /07/04

输出样例3

2022/07/04-Jack:"I have a leading zero.";
2022/7/4-Jack:"I dont have leading zero";
2022/7/04-Jack:"We have the same meaning!";
2022/07/04-Jack:"I have a leading zero.";
2022/7/4-Jack:"I dont have leading zero";
2022/7/04-Jack:"We have the same meaning!";

第六部分:限制说明

  • 一行输入中可能包含多条消息,但一条消息只会完整地出现在一行内
  • 每条消息之间和每行末尾可能存在若干空白字符作为分隔(空格和制表符\t),也可能不存在。
  • 保证所有的消息和指令符合格式。
  • 保证输入的日期、用户名、正文都非空。
  • 对于日期,保证 $year \in [0, 9999], mounth \in [1, 12], day \in [0,31]$。日期中可能存在前导0,比如1可以表示为01月,258可以表示为0258年,且保证日期合法。以及包括前导0在内,年份的位数不超过4位,月、日的位数不超过两位(这条与上次作业不同)
  • qdate指令保证输入的日期中年月日三个参数不同时缺省
  • 发送者和接收者的用户名仅由大小写英文字母、数字组成。
  • 正文内容仅由大小写英文字母、数字、空格、四种标点符号(? ! , .)构成
  • 输入数据中所有内容均对大小写敏感
  • 如果一条消息中存在@用户的情况(对应前两种消息模式),则保证该信息中@+用户名结构后面一定有一个空格,而且@用户最多只会在一个消息中出现一次。
  • 输入数据不超过300行
  • 输入数据每行不超过10个消息
  • 输入数据总询问数不超过100条

第七部分:提示与警示

提示

日期的前导0并不影响日期本身的含义,查询时请按照日期本身的语义进行查询。具体可见我们给出的样例。

警示

不要试图Hack评测机,不要抄袭。如发现其他人的代码疑似存在上述行为,可向课程组举报。课程组感谢同学们为课程建设所作出的贡献。

第五次实验数据

点击下载


评论
  目录