#THU20151C. CSV 数据处理

    ID: 110 Type: Default 1000ms 256MiB Tried: 73 Accepted: 6 Difficulty: 5 Uploaded By: Tags>清华推研机试考研模拟STL字符串处理

CSV 数据处理

时间限制: 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:不会出现筛选操作