B. CSV 数据处理

    Type: Default 1000ms 256MiB

CSV 数据处理

You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.

时间限制: 1.0 秒

空间限制: 512 MB

题目描述

小明要处理一些以 CSV (Comma-Separated Values) 格式存储的数据文件。虽然并没有一个通行的 CSV 文件格式的标准,通过观察,小明对他所需要处理的 CSV 格式的数据总结如下:

一个 CSV 数据文件有若干行,每行有若干个被逗号分隔开的项目。一个项目可以是以下几种数据中的一种:

  • 一个字符串。本题中,一个字符串是指 1 到 255 个连续出现的字符。字符串中可以出现的字符有大写字母,小写字母,空格,逗号 ,,以及小数点 .。本题中出现的字符串不会只包含空格。
  • 一个整数。本题中出现的整数一定在 [109,109][-10^9, 10^9] 范围内。比如 -43123456780 都是合法的整数。
  • 一个日期。在这种情况下,日期一定会符合 <YEAR>/<MONTH>/<DAY> 的形式。其中 <YEAR><MONTH><DAY> 均为整数,/ 即为字符 /(注意:该字符在字符串数据中的不会出现)。如果月份或者日期是一位数,则既可以写作一位数字也可以在前面补一个零。如 1980 年的 1 月 1 号可以被写作 1980/01/011980/1/11980/1/01 或者 1980/01/1。本题中出现的日期中的年份一定在 1900 到 2100 年之间,且日期合法。

注意:CSV 中不会出现满足整数或日期的格式,但不满足整数或日期范围的数据。也不会出现格式非法的字符串(即可能出现范围之外的字符)。

不管是哪一种数据,在 CSV 中出现时都有可能在两侧带上一对双引号,处理的时候应该认为这个数据就是双引号之间的内容,不含双引号。比如 "12" 表示一个整数 12。"2015/3/14" 表示日期 2015 年 3 月 14 日,"CSV Co., Ltd." 是一个内容为 CSV Co., Ltd. 的字符串。双引号总是成对出现。

字符串中可能包含逗号,但是如果字符串包含逗号的话,则一定会用一对双引号括起来。此时的双引号内的逗号并不视为分隔两个项目的逗号。

此外,在数据两侧还可能有多余的空格,在处理的时候请忽略这些空格。但是如果空格在双引号内,则应当被看作字符串的一部分。

如果一对双引号里的内容不是一个字符串(也就是说,是一个整数或者一个日期),则该对双引号内不会出现空格。例如 "12 34" 表示一个字符串 12 34。而字符串不包含 / 字符,故只要双引号中的内容包含 /,则引号内的内容一定是一个合法的日期。

小明需要处理的 CSV 文件还满足以下性质:该文件的每行的项目个数恰好相同。第一行的所有项目都是字符串,且这些字符串只由大写字母组成,这些字符串是每一列的名字。列的名字不会重复。除了第一行以外的所有项目则是数据部分,这部分里任何一列的所有项目都属于同一类别(字符串,整数或日期)。你需要根据上述描述来判断每一列的内容所对应的数据类型。

小明希望你对这些数据进行以下两种类型的处理:

  • 排序。命令格式为 SORT <name>。其中 <name> 为某一列的名字。 你需要把所有数据根据指定列的内容进行排序:

    • 对于两个字符串 aabb,如果 aabb 的前缀则 a<ba \lt b,如果 bbaa 的前缀则 b<ab \lt a。否则,aabb 的大小关系由它们的第一个对应位置上不相同的字符决定。在这种情况下,在下表中越早出现的字符被认为越小,越应该排序排到前面:,.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(空格在 markdown 题面不可见,其排在逗号前面,特此注明);
    • 整数的排序方式是数值越小的数字排在越前面;
    • 日期的排序方式是日期越早排在越前面;
    • 不管是对哪一种数据进行排序,对于指定列内容相同的各行,都不应该改变它们的相对顺序。
  • 筛选。命令格式为 FILTER <name> <op> <value>。其中 <name> 为某一列的名字,<op> 是比较运算符,可以是以下五种符号中的一种 : =<<=>>=。你需要把所有数据根据指定列的内容进行筛选,保留指定列的值和 <value> 符合给定 <op> 关系的行,而删除剩余的行。例如,如果命令是 FILTER ID > 5,你就需要保留名字为 ID 的列的值大于 5 的所有行,而删除其余行。其余类型的比较关系和上述排序方式相同。保留的行之间的相对顺序不变。<value> 保证类型与指定列的数据类型相同。<value> 可能以双引号括起来。

上述两种操作的格式,每一项中间均用一个空格进行分隔。

在执行完给定的操作之后,小明希望你以之前描述过的 CSV 格式,把处理完的数据再输出出来。

小明希望你输出数据时不要在项目两侧添加任何多余的空格,并且只在必须用双引号的时候(即需要输出一个包含逗号或两侧有空格的字符串时)才使用双引号。此外,小明还要求你在输出日期的时候对于月份和日期一律输出两位数字(如果只有一位的话在前面补一个零)。

输入格式

从标准输入读入数据。

输入的第一行有两个正整数 n,mn,m,分别是待处理的 CSV 文件的长度和小明希望你进行操作的个数。

接下来的 nn 行是需要你处理的 CSV 文件的内容,具体内容格式见题目描述一栏。

接下来的 mm 行是小明希望你进行的操作,具体内容格式见题目描述一栏。你需要按顺序进行这些操作。

输出格式

输出到标准输出。

输出若干行(至少为 1 行),为执行完小明给定的操作以后的数据,按照题目描述一栏的格式进行输出。不难发现,行数最少的情况即为删除所有数据行,只保留表示每一列名字的第一行。

6 2
ID, NAME, BIRTHDATE, SCORE
1 , Xiao Ming , "1993/04/01" , 60
2, "Xiao Hong ",1993/05/05,98
3, "Zhang San" ,1993/10/27,33
4,Li Si,1994/12/25,"94"
5, "Wang Wu,,,,,",1993/09/11,76
FILTER SCORE >= "60"
SORT BIRTHDATE
ID,NAME,BIRTHDATE,SCORE
1,Xiao Ming,1993/04/01,60
2,"Xiao Hong ",1993/05/05,98
5,"Wang Wu,,,,,",1993/09/11,76
4,Li Si,1994/12/25,94

样例 1 解释

该样例所表示的 CSV 文件一共有 6 行,小明给出的操作有 2 次。

CSV 文件的第 1 行为各列的所有名字。接下来的第 2 至 6 行为具体信息。根据第 2 行的内容,可以判断出各列的数据类型 : ID 为整数,NAME 为字符串,BIRTHDATE 为日期,SCORE 为整数,共计 4 列。

第一次操作,只保留 SCORE 大于等于 60 的行。故原始 CSV 文件的第 4 行被删除。

第二次操作,需要根据 BIRTHDATE 从小到大进行排序。

在输出 NAME 当中,Xiao Ming 中间的空格需要保留,右侧的空格需要去掉。"Xiao Hong " 内部最右侧的空格需要保留,输出时需要保留双引号。"Wang Wu,,,,," 在输出时也需要保留双引号。SCORE 当中的 94 需要去掉引号再输出。若 CSV 文件的第 4 行未被删除,其 NAME 一栏的 "Zhang San" 需要去掉外层的双引号再输出。

子任务

对于所有数据,保证 2n1000, 1m102\le n\le 1000,~1\le m\le 10,被处理的 CSV 文件的每行的项目不超过 1010 个。

测试点编号 特殊性质
1 A,B,C
2 A,B,D
3 A,C
4 A
5 B,D
6 B
7 C
8 D
9
10
  • 特殊性质 A:不会出现双引号
  • 特殊性质 B:不会出现日期
  • 特殊性质 C:不会出现排序操作
  • 特殊性质 D:不会出现筛选操作