北邮OJ-258-数据库检索-14软院上机D

  本题在大的方向上由于两个问题而一直超时:
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;
} 

你可能感兴趣的:(北邮OJ-14软院)