首页 > 代码库 > POJ1035 Spell-checker(哈希,串处理)

POJ1035 Spell-checker(哈希,串处理)

本文出自:http://blog.csdn.net/svitter


题意: 检查字典。

一开始,输入字典中的字符,以#结束。

随后,输入查询的字符,以#结束。

其中,符合要求的查询项目有:

1.去除一个字符,可以匹配

2.取代一个字符,可以匹配

3.添加一个字符,可以匹配

输入输出分析:

1.注意不要将#包含进入字典。

2.对于每一个字符进行分析。

题目分析:

使用哈希表或者直接暴力解题。

一个字符指针指向要查询的单词,一个字典指针指向字典中的单词。

分为三种处理情况:

1.对于去除一个字符的情况,可以移动一次字符指针,字符长度为字典长度+1

2.对于取代一个字符情况,同时移动两个指针一次,字符长度=字典长度

3.对于添加一个字符的情况,移动一次字典指针,字符长度+1=字典长度


AC代码,864MS://单纯使用串的情况。

//author: svtter
//
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#define INF 0xffffff

using namespace std;

char dict[10010][16];
char temp[16];
bool del(char *word, char *dic);
bool rep(char *word, char *dic);
bool add(char *word, char *dic);

int main()
{
    int i;
    int nDict;
    char *word, *dic;
    bool operation;
    bool get = false;

    for(i = 0; i < 10002; i++)
    {
        scanf("%s", dict[i]);
        if(dict[i][0] == '#')
        {
            nDict = i;
            break;
        }
    }
    //Do something

    //printf("now input words: \n");

    while(scanf("%s", temp))
    {
        if(temp[0] == '#')//stop condition
            break;

        word = temp;
        get = false;
        for(i = 0; i < nDict; i++)
        {
            dic = dict[i];
            if(strcmp(word, dic) == 0)
            {
                printf("%s is correct\n", word);
                get = 1;
                break;
            }
        }

        if(!get)
        {
            printf("%s:", word);
            for(i = 0; i < nDict; i ++)//del operation
            {
                dic = dict[i];
                operation = del(word, dic);
                if(operation)
                {
                    printf(" %s", dic);
                    get = 1;
                }
                operation = rep(word, dic);
                if(operation)
                {
                    printf(" %s", dic);
                    get = 1;
                }
                operation = add(word, dic);
                if(operation)
                {
                    printf(" %s", dic);
                    get = 1;
                }
            }
            printf("\n");
        }
    }
    return 0;
}

bool del(char *word, char *dic)
{
    int dis = strlen(word) - strlen(dic);
    if(dis != 1)
        return false;
    int diff = 0;
    while(*word)
    {
        if(*word != *dic)
        {
            word++;
            diff++;
            if(diff > 1)
                return false;
        }
        else
        {
            word++;
            dic++;
        }
    }
    return true;
}

bool rep(char *word, char *dic)
{
    int dis = strlen(word) - strlen(dic);
    if(dis != 0)
        return false;
    int diff = 0;
    while(*word)
    {
        if(*word != *dic)
        {
            word++;
            dic++;
            diff++;
            if(diff > 1)
                return false;
        }
        else
        {
            word++;
            dic++;
        }
    }
    return true;
}

bool add(char *word, char *dic)
{
    int dis = strlen(word) - strlen(dic);
    if(dis != -1)
        return false;
    int diff = 0;
    while(*word)
    {
        if(*word != *dic)
        {
            dic++;
            diff++;
            if(diff > 1)
                return false;
        }
        else
        {
            dic++;
            word++;
        }
    }
    return true;
}


AC代码,使用hashtable的情况://参照了大神的代码,不过出处已经找不到了。

/*
题意:输入字典,然后输入单词,判断字典中是否出现过该单词,或者是否进行删除、添加、替换操作,如果是,则输出对应的字典中的单词
要求按照输入时候的排名输出

题解:建立两个哈希表。一个存储字典和输入字典中单词的排名,一个进行最后输出的判重
*/

#include <iostream>
#include <string.h>
#include <cstdio>
#include <algorithm>
//#define
using namespace std;
const int HASH = 12007;
char list1[HASH][18];
int rank[HASH];
int head1[HASH];

char list2[HASH][18];
int head2[HASH];

int ans[10007];
int ansLen;

char word[57];
char tempWord[57];


int insert1(char *s, int pos)
{
    int len = strlen(s);
    int i, k = 0;
    for(i = 0; i < len; ++ i)
        k = (k * 26 + s[i] - 'a') % HASH;
    while(head1[k] != 0 && strcmp(list1[k], s) != 0)
    {
        k = (k + 1) % HASH;
    }
    if(!head1[k])
    {
        head1[k] = 1;
        strcpy(list1[k], s);
        rank[k] = pos;
        return 1;
    }
    return 0;
}

int insert2(char *s)
{
    int len = strlen(s);
    int i, k = 0;
    for(i = 0; i < len; ++ i)
        k = (k * 26 + s[i] - 'a') % HASH;
    while(head2[k] != 0 && strcmp(list2[k], s) != 0)
    {
        k = (k + 1) % HASH;
    }
    if(!head2[k])
    {
        head2[k] = 1;
        strcpy(list2[k], s);
        return 1;
    }
    return 0;
}

int exist(char *s)
{
    int len = strlen(s);
    int i, k = 0;
    for(i = 0; i < len; ++ i)
        k = (k * 26 + s[i] - 'a') % HASH;
    while(head1[k] != 0 && strcmp(list1[k], s) != 0)
    {
        k = (k + 1) % HASH;
    }
    if(!head1[k])
    {
        return -1;
    }
    return k;
}

int cmp(const void *a, const void *b)
{
    int *pa = (int *) a;
    int *pb = (int *) b;
    return rank[*pa] - rank[*pb];
}

int main()
{
    //int flag = 0;
    //freopen("e://data.in", "r", stdin);
    while(gets(word))
    {
        memset(head1, 0, sizeof(head1));

        int pos = 0;
        while(word[0] != '#')
        {
            insert1(word, pos ++);
            gets(word);
        }
        gets(word);
        while(word[0] != '#')
        {
            memset(head2, 0, sizeof(head2));
            ansLen = 0;
            printf("%s", word);
            if(exist(word) > -1)
            {
                printf(" is correct\n");
                gets(word);
                continue;
            }
            int len = strlen(word);
            int i, k;
            char j;
            int z;
            for(i = 0; i <= len; ++ i)
            {
                strcpy(tempWord, word);
                for(k = len; k >= i; k --)
                    tempWord[k + 1] = tempWord[k];
                for(j = 'a'; j <= 'z'; ++ j)
                {
                    tempWord[i] = j;
                    if((z = exist(tempWord)) > -1 && insert2(tempWord))
                    {
                        ans[ansLen ++] = z;
                    }
                }
            }
            for(i = 0; i < len; ++ i)
            {
                strcpy(tempWord, word);
                for(k = i + 1; k <= len; ++ k)
                    tempWord[k - 1] = tempWord[k];
                if((z = exist(tempWord)) > -1 && insert2(tempWord))
                {
                    ans[ansLen ++] = z;
                }
            }
            for(i = 0; i < len; ++ i)
            {
                strcpy(tempWord, word);
                for(j = 'a'; j <= 'z'; ++ j)
                {
                    tempWord[i] = j;
#ifdef TEST
                    if(j == 'd')
                    {
                    printf("\n");
                    }
#endif
                    if((z = exist(tempWord)) > -1 && insert2(tempWord))
                    {
                        ans[ansLen ++] = z;
                    }
                }
            }
            qsort(ans, ansLen, sizeof(ans[0]), cmp);
            printf(":");
            for(i = 0; i < ansLen; ++ i)
                printf(" %s", list1[ans[i]]);
            printf("\n");
            gets(word);
        }
    }
    return 0;
}