ZOJ 1109 Language of FatMouse

主要是字符串查找,有多种解法:

算法一:Trie(时间效率最高)(27888KB)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int CHAR_LEN = 11; /* 单词长度 */
const int ALPH_LEN = 26; /* 字母个数 */
const int MAX = 22; /* 一行字符串的最大长度 */
const char EXIST = ‘1‘; /* 存在为‘1‘, ‘0‘反之 */
const char NON_EXIST = ‘0‘;
const int ZERO = 0;
const char FIRST_CHAR = ‘a‘;

/* 字典树建立 */
typedef struct node {
    struct node *child[ALPH_LEN];
    char trans[CHAR_LEN]; /* 翻译 */
    char exist; /* 判断是否存在此FatMouse单词 */
}node, *Node;
Node root; /* 字典树根结点 */

/* 插入FatMouse单词和相应的翻译 */
void insert(char *fatM, char *trans)
{
    int i, index, len;
    Node current = NULL, newnode = NULL; /* 当前结点和新结点 */

    len = strlen( fatM );
    if (ZERO == len) /* 单词长度为0, 不需要插入 */
    {
        return;
    }

    current = root; /* 每次插入都要从根结点开始 */
    for (i = 0; i < len; i++)
    {
        index = fatM[i] - FIRST_CHAR; /* 获取下标 */
        if (NULL != current->child[index]) /* 当前字符存在字典树中 */
        {
            current = current->child[index];
        }
        else
        {
            if ((newnode=(Node) calloc (1, sizeof(node))) == NULL) {
                printf("空间分配失败!\n");
                exit( -1 );
            }

            current->child[index] = newnode; /* 插入新结点 */
            current = newnode; /* 修改当前结点位置 */
        }
    }

    strcpy(current->trans, trans); /* 保存翻译 */
    current->exist = EXIST; /* 此fatMouse单词存在 */
}

/* 翻译 */
void translate(const char *fatM)
{
    int i, index, len;
    Node current = NULL; /* 当前结点 */

    len = strlen( fatM );
    if (ZERO == len) /* 此单词为空, 不需要翻译 */
    {
        return;
    }

    current = root; /* 每次都要从根结点开始搜 */
    for (i = 0; i < len; i++)
    {
        index = fatM[i] - FIRST_CHAR; /* 获取下标 */
        if (NULL != current->child[index]) /* 当前结点存在字典树中 */
        {
            current = current->child[index]; /* 修改当前位置 */
        }
        else
        {
            puts("eh");
            return;
        }
    }

    /* 判断并输出(匹配不一定存在字典树中) */
    if (current->exist == EXIST) /* 此fatMouse单词存在字典树中 */
    {
        puts(current->trans);
    }
    else
    {
        puts("eh");
    }
}

/* 释放内存 */
void release(Node root)
{
    int i;

    for (i = 0; i < ALPH_LEN; i++)
    {
        if (NULL != root->child[i])
        {
            release( root->child[i] ); /* 释放孩子结点 */
        }
    }

    free( root ); /* 释放 */
    root = NULL; /* 指针置空 */
}

int main()
{
    char trans[CHAR_LEN], fatM[CHAR_LEN];
    char tmp[MAX]; /* 接收一行 */
    int i, len;

    if ((root=(Node) calloc (1, sizeof(node))) == NULL) {
        printf("空间分配失败!\n");
        exit(-1);
    }
    while (gets(tmp), len = strlen(tmp))
    {
        for (i = 0; i < len; i++)
        {
            if (tmp[i] == ‘ ‘)
            {
                break;
            }
        } /* 寻找分隔点 */

        /* 找出两个单词 */
        strcpy(fatM, tmp + i + 1);
        tmp[i] = ‘\0‘;
        strcpy(trans, tmp);

        insert(fatM, trans); /* 插入, 建立字典树 */
    }

    while (scanf("%s", fatM) != EOF)
    {
        translate( fatM );
    }

    return 0;
}

牛人带注释版60ms

#include"iostream"
using namespace std;
#include"cstring"
#include"cstdio"
#include"malloc.h"
struct trie{
    trie *next[26];
    bool flag;
    char s[12];
};
trie *root;
void insert(char *s,char *ans)
{
    int id,l=strlen(s);
    trie *p=root,*q;
    for(int i=0;i<l;i++)
    {
        id=s[i]-‘a‘;
        if(p->next[id]==NULL) {
            q=(trie*)malloc(sizeof(trie));
            q->flag=false;
            for(int j=0;j<26;j++) q->next[j]=NULL;
            p->next[id]=q;
        }
        p=p->next[id];
    }
    p->flag=true;
    strcpy(p->s,ans);
}
bool can(trie *p)
{
    for(int i=0;i<26;i++)
        if(p->next[i]) return 1;
    return 0;
}
void search(char *s)
{
    int l=strlen(s);
    trie *p=root,*q;
    for(int i=0;i<l;i++)
    {
        q=p->next[s[i]-‘a‘];
        if(q!=NULL) p=q;
            else break;
    }
//    if(q!=NULL&&q->flag&&can(q))
//    {
//        while(can(q))
//        for(int i=0;i<26;i++)
//        if(q->next[i]) { putchar(‘a‘+i); q=q->next[i]; }
//        puts("");
//    }
//        else puts("eh");
    if(q!=NULL&&q->flag) puts(q->s);
        else puts("eh");
}
int main()
{
    char s[30],key[30],ans[15];
    root=(trie*)malloc(sizeof(trie));
    for(int i=0;i<26;i++) root->next[i]=NULL;
    while(gets(s))
    {
        if(!s[0]) break;
        sscanf(s,"%s%s",ans,key);
        insert(key,ans);
    }
    while(gets(s))
    {
        search(s);
    }
    return 0;
}

我自己写的70ms

算法二:快排后二分查找()

#include"iostream"
using namespace std;
#include"algorithm"
#include"cstdlib"
#include"cstdio"
#include"cstring"
struct dic{
    char key[11],ans[11];
}d[100010];
int cmp(const void *a,const void *b)
{
    dic *x=(dic*)a;
    dic *y=(dic*)b;
    return strcmp((x->key),(y->key));
}
int main()
{
    char s[24];
    int n=0;
    while(gets(s))
    {
        if(!strlen(s)) break;
        sscanf(s,"%s%s",d[n].ans,d[n].key);
        ++n;
    }
    qsort(d,n,sizeof(d[0]),cmp);
    dic *res=NULL;
    while(gets(s))
    {
        res=(dic*)bsearch(s,d,n,sizeof(d[0]),cmp);
        if(res!=NULL) puts(res->ans);
            else puts("eh");
    }
    return 0;
}

C版,100ms,4568KB

//sort效率笔qosrt高,貌似lower_bound()拖慢了很多
#include"iostream"
using namespace std;
#include"algorithm"
#include"vector"
#include"cstdio"
#include"cstdlib"
#include"cstring"

struct dic
{
    char key[12];
    char ans[12];
    bool operator<(const dic a) const
    {
        return strcmp(key,a.key)<0;
    }
//    bool operator==(const dic a) const
//    {
//        return strcmp(key,a.key)==0;
//    }
};

dic v[100010];
int main()
{
    //freopen("d:\\in.txt","r",stdin);
    //freopen("d:\\out.txt","w",stdout);
    dic c; int n=0;
    char s[30];
    while(gets(s))
    {
        if(!s[0]) break;
        sscanf(s,"%s%s",v[n].ans,v[n].key);

        n++;
    }

    sort(v,v+n);
    //for(int i=0;i<n;i++) cout<<v[i].key<<‘ ‘<<v[i].ans<<endl;

    while(gets(s))
    {
        strcpy(c.key,s);
        dic *i=lower_bound(v,v+n,c);
        //cout<<i-v<<endl;
        if(i!=v+n&&strcmp(s,i->key)==0)
            cout<<i->ans<<endl;
        else cout<<"eh"<<endl;
    }
    return 0;
}

C++版,940ms-1010ms,不稳定,人品不好会超时

#include"iostream"
using namespace std;
#include"algorithm"
#include"vector"
#include"cstdio"
#include"cstdlib"
#include"cstring"

struct dic
{
    char key[12];
    char ans[12];
    bool operator<(const dic a) const
    {
        return strcmp(key,a.key)<0;
    }
};

dic v[100010];
//int l,r,m,cmp; bool ok;
int main()
{
    //freopen("d:\\in.txt","r",stdin);
    //freopen("d:\\out.txt","w",stdout);
    int n=0;
    char s[30];
    while(gets(s))
    {
        if(!s[0]) break;
        sscanf(s,"%s%s",v[n].ans,v[n].key);
        n++;
    }
    sort(v,v+n);
//    for(int i=0;i<n;i++) cout<<v[i].key<<‘ ‘<<v[i].ans<<endl;
    while(gets(s))
    {
//        strcpy(c.key,s);
//        dic *i=lower_bound(v,v+n,c);
//        cout<<i-v<<endl;
//        if(i!=v+n&&strcmp(s,i->key)==0)
//            cout<<i->ans<<endl;
//        else cout<<"eh"<<endl;
//        l=ok=0; r=n-1;
//        while(l<=r)
//        {
//            m=(l+r)>>1;
//            cmp=strcmp(v[m].key,s);
//            if(cmp==0) {ok=1; break;}
//            else if(cmp>0) r=m-1;
//            else l=m+1;
//        }
//        if(ok) puts(v[m].ans); else puts("eh");
        int l=n-1,first=0,m,h;
        while(l>0)
        {
            h=l>>1;
            m=first+h;
            if(strcmp(v[m].key,s)<0) { first=m+1; l=l-h-1; }
                else l=h;
        }
        if(strcmp(v[first].key,s)==0) puts(v[first].ans); else puts("eh");
    }
    return 0;
}

sort+自写二分,100ms

lower_bound也是二分查找啊,为何拖慢了这么多,找到源码自己写也是100ms,结构体比较sort正常,不知道lower_bound为什么这么慢!

c++的只用2616KB

算法三:Map映射(1300ms,15848KB)

"STL的map的查找时间复杂度在任何时候总是O(logN),因为map用的是红黑树,可以保证树的高度总是logN。"

#include"iostream"
using namespace std;
#include"map"
#include"cstdio"
#include"string"
#include"algorithm"
map<string,string> m;
int main()
{
    //freopen("d:\\in.txt","r",stdin);
    //freopen("d:\\out.txt","w",stdout);
    string s;
    while(getline(cin,s))
    {
        if(s.size()==0) break;
        int pos = s.find(‘ ‘);
        m[s.substr(pos+1)]=s.substr(0,pos);
    }
    while(cin>>s)
    {
        if(m.find(s)==m.end()) cout<<"eh"<<endl;
        else cout<<m[s]<<endl;
    }
    return 0;
}

算法四: 二叉查找树(190ms,12576KB)

#include <stdio.h>
#include <stdlib.h>
#include <memory>
#include <string>
#include <string.h>

using namespace std;

struct node
{
    char key[50],value[50];
    struct node *left,*right;
}*Head;
void insert(const char *elem,const char *value,struct node * & p)
{
    if( p == NULL)
    {
        p = (struct node*)malloc(sizeof(struct node));
        strcpy(p->key,elem);
        strcpy(p->value,value);
        p->left = p->right = NULL;
        return ;
    }
    if( strcmp(elem,p->key)>0 )
        insert(elem,value,p->right);
    else
        insert(elem,value,p->left);
}

void find(const char *key,struct node *&p)
{
    if(p==NULL)
        printf("eh\n");
    else if(strcmp(key,p->key)==0)
        printf("%s\n",p->value);
    else if(strcmp(key,p->key)>0)
        find(key,p->right);
    else
        find(key,p->left);
}

int main(void)
{
    char str[100],key[50],value[50];

    while(gets(str) && strlen(str))
    {
        sscanf(str,"%s%s",value,key);
        insert(key,value,Head);
    }

    while(scanf("%s",key)!=EOF)
    {
        find(key,Head);
    }
    Head=NULL;
    return 0;
}

排序二叉树

时间: 2024-08-12 07:59:13

ZOJ 1109 Language of FatMouse的相关文章

zoj 1109 Language of FatMouse(字典树)

Language of FatMouse Time Limit: 10 Seconds      Memory Limit: 32768 KB We all know that FatMouse doesn't speak English. But now he has to beprepared since our nation will join WTO soon. Thanks to Turing we havecomputers to help him. Input Specificat

【输入回车结束输入】Language of FatMouse

Language of FatMouse 时间限制: 1 Sec  内存限制: 64 MB 提交: 86  解决: 54 [提交][状态][讨论版] 题目描述 We all know that FatMouse doesn't speak English. But now he has to be prepared since our nation will join WTO soon. Thanks to Turing we have computers to help him. 输入 Inp

字典树(Trie)

 字典树:又称为Trie,是一种用于快速检索的多叉树结构.Trie把要查找的关键词看作一个字符序列,并根据构成关键词字符的先后顺序构造用于检索的树结构:一棵m度的Trie树或者为空,或者由m棵m度的Trie树构成. 注意:和二叉查找树不同的是,其节点并非存储一个元素. 优点:1.利用公共内存,以达到节约内存的目的 2.根节点只存储其子树,不存储字母 3.每个节点代表的字母都不同 基本定义: typedef struct Node { struct Node*child[26]; int n;

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较

codeforces 499B.Lecture 解题报告

题目链接:http://codeforces.com/problemset/problem/499/B 题目意思:给出两种语言下 m 个单词表(word1, word2)的一一对应,以及 professor's lecture 的 n 个单词.问记下来的笔记是什么.对于professor's lecture 的某个单词,如果在单词表中找到,word1, word2 都有可能.如果 word1 的长度  <= word2 的长度,就输出word1,否则word2 考了map<string, st

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

zoj1109-Language of FatMouse

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=109 Language of FatMouse Time Limit: 10 Seconds      Memory Limit: 32768 KB We all know that FatMouse doesn't speak English. But now he has to be prepared since our nation will join WTO soon.

ZOJ1109_Language of FatMouse(STL/map)

解题报告 题意: 略. 思路: map应用. #include <algorithm> #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <cstdio> #include <map> using namespace std; map<string,stri

待刷题目分类

各大OJ题目归类 Posted on 2012 年 8 月 8 日 by admin ---------–最优化问题------------- --------动态规划 SOJ1162 I-Keyboard SOJ2096 Maximum Submatrix SOJ2111 littleken bg SOJ2505 The County Fair SOJ2818 QQ音速 SOJ2469 Exploring Pyramids SOJ1833 Base Numbers SOJ2009 Zeros