本题在大的方向上由于两个问题而一直超时:
1. 由于要提取查询串的子串,故全程使用了string类以及其substr方法,开销较大
2. 使用了vector来存储结构体,在记录答案时选择了把match的答案push进新的vector,这带来了很大的开销。
于是着手对这两个问题进行改进(=皿=真踏马比重写还累)。
1. 采用char数组与strncpy函数来替代,发现实现的功能几乎一毛一样!唯一坑爹的地方就是要注意:strcpy是会自动在dst串后补全’\0’的,而strncpy并不补!要记得手动补齐!(是的没错我就是在这里出了bug)
2. 采用isAns[]做标记,来替代结构体的推来推去!
终于不超时了。。。。
经验教训:(算是bug记录吧)
1. 能使用char[]就尽量别用string,因为目前用到的string功能好像都能通过char[]实现,而且也不太麻烦
2. 能标记尽量不要去各种push结构体!消耗太大!
3. 即使代码段相似度很高。。。尽量也用写的别复制粘贴。。。由于参数没改过来出了一堆bug找都找不到。。。血的教训
4. 还学到了一个新东西:c++的vector erase中间的元素也不会出现空洞,不知道为毛!反正会自动修正就对了。迭代erase的时候记得erase之后i要回退(是的出bug了)
Problem D. 数据库检索
题目描述
在数据库的操作过程中,我们进场会遇到检索操作。这个题目的任务是完成一些特定格式的检索,并输出符合条件的数据库中的所有结果。
我们现在有一个数据库,维护了学生的姓名(Name),性别(Sex)以及出生日期(Birthday)。其中,Name项是长度不超过30的字符串,只可能包含大小写字母,没有空格;Sex项进可能为‘Male’或者‘Female’(不含引号);Birthday项以yyy/mm/dd的格式存储,如:1990/01/01,
1991/12/31,等等。
每个查询所可能包含的条件如下:
Name=‘REQUIRED_NAME’,查询姓名为REQUIRED_NAME的学生,其中REQUIRED_NAME为长度在1到30之间的字符串;
Sex=‘Male’或Sex=‘Female’,查询性别为男/女的学生;
Birthday=‘yyy/mm/dd’,查询出生年/月/日为特定值的学生。如果其中某项为’’,则说明该项不受限制。例如,‘1990/06/’表示1990年6月出生,‘/03/’表示出生月份为3月。
给定数据库的所有表项以及若干条查询,你需要对每条查询输出它返回的结果。
输入格式
输入包含多组测试数据。输入的第一行为测试数据的组数T(1<=T<=50)。
对于每组测试数据,第一行是两个整数N和M(N,M<=500),分别表示数据的数量以及查询的数量。
接下来N行,每行以Name Sex Birthday的形式给出每个学生的信息。
没下来M行,每行给出若干条限制条件,以空格隔开。条件以Name Sex Birthday的顺序给出(如果存在),且每种限制条件最多只出现一次。
输出格式
对于每条查询,按照输入的顺序输出符合条件的学生姓名,每个一行。如果没有符合查询的信息,则输出一行NULL。
样例输入
1
5 6
Michael Male 1990/02/28
Amy Female 1992/04/03
Tom Male 1991/12/15
Lynn Female 1991/04/09
Zheng Male 1990/04/20
Name=’Amy’
Name=’Betty’
Sex=’Female’ Birthday=’*/04/09’
Sex=’Female’ Birthday=’//*’
Name=’Michael’ Sex=’Female’
Name=’Michael’ Sex=’Male’ Birthday=’1990/02/*’
样例输出
Amy
NULL
Lynn
Amy
Lynn
NULL
Michael
#include
#include
#include
#include
#include
#define MAXSIZE 550
#define MAXSIZE_MEM 40
#define MAXSIZE_STR 200
using namespace std;
struct Student;
int t,n,m;
vector stu;
bool isAns[MAXSIZE];
void processDate(char *birthday,char *year,char *month,char *day);
struct Student{
char name[MAXSIZE_MEM];
char sex[MAXSIZE_MEM];
char birthday[MAXSIZE_MEM];
char year[MAXSIZE_MEM];
char month[MAXSIZE_MEM];
char day[MAXSIZE_MEM];
Student(){
}
Student(char* name,char* sex,char* birthday){
strcpy(this->name,name);
strcpy(this->sex,sex);
strcpy(this->birthday,birthday);
processDate(birthday,year,month,day);
}
};
void processDate(char *birthday,char *year,char *month,char *day){
int start=0;
int p=0;
while (birthday[p]!='/'){
p++;
}
strncpy(year,&birthday[start],p-start);/*bug*/
year[p-start]='\0';/*bug*/
p++;start=p;
while (birthday[p]!='/'){
p++;
}
strncpy(month,&birthday[start],p-start);
month[p-start]='\0';
p++;start=p;
while (birthday[p]!='\0'){
p++;
}
strncpy(day,&birthday[start],p-start);
day[p-start]='\0';
}
void queryName(char* str){//str只包含纯"名字"
//search
for (int i=0;iif (isAns[i]){
if (strcmp(stu[i].name,str)!=0){
isAns[i]=false;
//i--;/*bug*/
}
}
}
}
void querySex(char* str){
//search
for (int i=0;iif (isAns[i]){
if (strcmp(stu[i].sex,str)!=0){
isAns[i]=false;
// i--;
}
}
}
}
void queryBirthday(char* str){
char year[MAXSIZE_MEM],month[MAXSIZE_MEM],day[MAXSIZE_MEM];
//preprocess
processDate(str,year,month,day);
//search
for (int i=0;iif (isAns[i]){
bool matched=true;
if (!(strcmp(year,"*")==0||strcmp(stu[i].year,year)==0))
matched=false;
else if (!(strcmp(month,"*")==0||strcmp(stu[i].month,month)==0))
matched=false;
else if (!(strcmp(day,"*")==0||strcmp(stu[i].day,day)==0))
matched=false;
if (!matched){
isAns[i]=false;
}
}
}
}
void query(char* queryStr){
char tempStr[MAXSIZE_MEM];//存储每次查询中的某项条件
char item[MAXSIZE_STR];
int start=0;
int p=0;
while (true){
//preprocess
while (queryStr[p]!=' '&&queryStr[p]!='\0'){
p++;
}
strncpy(tempStr,&queryStr[start],p-start);
tempStr[p-start]='\0';
//visit
if (tempStr[0]=='N'){
int x=6;
int y=6;
while (tempStr[y]!='\''){
y++;
}
strncpy(item,&tempStr[x],y-x);
item[y-x]='\0';
queryName(item);
}
else if (tempStr[0]=='S'){
int x=5;
int y=5;
while (tempStr[y]!='\''){
y++;
}
// cout<
strncpy(item,&tempStr[x],y-x);
item[y-x]='\0';
querySex(item);
}
else if (tempStr[0]=='B'){
int x=10;
int y=10;
while (tempStr[y]!='\''){
y++;
}
strncpy(item,&tempStr[x],y-x);
item[y-x]='\0';
queryBirthday(item);
}
//postprocess
if (queryStr[p]=='\0'){
break;
}
p++;
start=p;
}
}
void printAns(){
bool haveAns=false;
for (int i=0;iif (isAns[i]==true){
haveAns=true;
printf("%s\n",stu[i].name);
}
}
if (haveAns==false)
printf("NULL\n");
}
int main(){
char name[MAXSIZE_MEM],sex[MAXSIZE_MEM],birthday[MAXSIZE_MEM];
char queryStr[MAXSIZE_STR];
char queryChar[MAXSIZE_STR];
scanf("%d",&t);
for (int time=0;time//initiate
stu.clear();
//input
scanf("%d%d",&n,&m);
for (int i=0;iscanf("%s%s%s",name,sex,birthday);
stu.push_back(Student(name,sex,birthday));
}
//debug**
// for (int i=0;i
// printf("%s %s %s %s %s %s\n",stu[i].name,stu[i].sex,stu[i].birthday,stu[i].year,stu[i].month,stu[i].day);
// }
//*******
//search
bool firstCase=true;
for (int i=0;i//initiate
for (int i=0;itrue;
}
//input
if (firstCase){//吸收回车
getchar();
firstCase=false;
}
gets(queryStr);
query(queryStr);
//output
printAns();
}
}
return true;
}