UVA - 10815 Andy's First Dictionary

来源:互联网 发布:淘宝交保证金流程 编辑:程序博客网 时间:2024/06/03 13:29

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18649

给你一段不超过5000行的文本,让你从中找出所有的单词,并且按照字典序排序,注意不区分大小写。

题目意思还是很好懂的,但是开始误认为单词总数不超过5000,但是还有很多重复的,于是不幸的run  error,所以数组最少需要开到10万去,并且普通排序是必然超时的!这里用qsort。

#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>using namespace std;char str[100200][210];int cmp(const void* s1,const void* s2){    return strcmp((char*)s1,(char*)s2);}int main(){    freopen("a.txt","r",stdin);    char s[210],ss[210];    int i,j,k=0;while(gets(s))    {        memset(ss,'\0',sizeof(ss));        j=0;        int l=strlen(s);        for(i=0;i<l;i++)        {            if(s[i]>='A'&&s[i]<='Z')  //把大写字母转化成小写字母            {                s[i]+=32;            }            if(s[i]>='a'&&s[i]<='z')            {                ss[j++]=s[i];  //保存单词            }            if(j)  //必须是单词才能下一步,            {                if((i==l-1)||(!(s[i]>='a'&&s[i]<='z')))                {                    strcpy(str[k++],ss); //复制单词到数组中                    memset(ss,'\0',sizeof(ss));                    j=0;                }            }        }    }   /* for(i=0;i<k;i++) //冒泡超时    {        for(j=i+1;j<k;j++)        {            if(strcmp(str[i],str[j])>0)            {                memset(ss,'\0',sizeof(ss));                strcpy(ss,str[i]);                strcpy(str[i],str[j]);                strcpy(str[j],ss);            }        }    }*/    qsort(str,k,sizeof(str[0]),cmp); //排序    printf("%s\n",str[0]);    memset(ss,'\0',sizeof(ss));    strcpy(ss,str[0]);    for(i=1;i<k;i++)  //防止重复    {        if(strcmp(str[i],ss)!=0)        {            printf("%s\n",str[i]);            strcpy(ss,str[i]);        }        else strcpy(ss,str[i]);    }return 0;}


学到了用sort对二维数组进行排序,另外开了一个char *strp[maxn]一个指针的字符串数组,然后strp[i]指向的是str数组每一行的首地址,直接对strp进行排序,对指针还是掌握的远远不够。并且sort是qsort的优化版本,耗时比qsort少。

#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>using namespace std;char str[100200][210];char *strp[100200];bool cmp(const char* s1,const char* s2){    return strcmp(s1,s2)<0;}int main(){    //freopen("a.txt","r",stdin);    char s[210],ss[210];    int i,j,k=0;while(gets(s))    {        memset(ss,'\0',sizeof(ss));        j=0;        int l=strlen(s);        for(i=0;i<l;i++)        {            if(s[i]>='A'&&s[i]<='Z')  //把大写字母转化成小写字母            {                s[i]+=32;            }            if(s[i]>='a'&&s[i]<='z')            {                ss[j++]=s[i];  //保存单词            }            if(j)  //必须是单词才能下一步,            {                if((i==l-1)||(!(s[i]>='a'&&s[i]<='z')))                {                    strcpy(str[k++],ss); //复制单词到数组中                    memset(ss,'\0',sizeof(ss));                    j=0;                }            }        }    }    for(i=0;i<k;i++)    {        strp[i]=str[i];    }    sort(strp,strp+k,cmp);    printf("%s\n",strp[0]);    memset(ss,'\0',sizeof(ss));    strcpy(ss,strp[0]);    for(i=1;i<k;i++)  //防止重复    {        if(strcmp(strp[i],ss)!=0)        {            printf("%s\n",strp[i]);            strcpy(ss,strp[i]);        }        else strcpy(ss,strp[i]);    }return 0;}

还有一个不用gets的,用getchar读字符,速度远远比gets慢。也可能是判重的影响,

#include<cstdio>#include<ctype.h>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100005;char str[maxn][210];char *strp[maxn];bool cmp(const char *s1,const char *s2){    return strcmp(s1,s2)<0;}int main(){    //freopen("a.txt","r",stdin);    char c,s[210];    int i,j=0,cnt=0,flag;    while((c=getchar())!=EOF)    {        if(isalpha(c)) s[j++]=tolower(c);        else if(j)        {            s[j]='\0';            for(i=0,flag=0;i<cnt;i++)            {                if(strcmp(s,str[i])==0) {flag=1;break;}            }            if(!flag) strcpy(str[cnt++],s);            j=0;        }    }    for(i=0;i<cnt;i++)    {        //printf("%s\n",str[i]);        strp[i]=str[i];    }    sort(strp,strp+cnt,cmp);    for(i=0;i<cnt;i++)    {        printf("%s\n",strp[i]);    }    return 0;}




0 0