利用散列结构查找字谜

摘要:曾经我们用最基本的查找方法查找过字谜问题,如果字谜用二维数组存放(R*C),要查找的单词个数为w,则时间界是O(RCW).
现在改用散列存放要查找的单词,由于散列的查找时间为常数,那么时间界在理论上可以降至O(RC),
注意细节:(1)可以添加一个前缀变量,当搜索方向的上的字符串不属于某个单词的前缀,就停止对该单词的匹配.(这可以显著提高效率,但是需要加很多额外代码)

#include "stdafx.h"
#include "stdlib.h"
#include "malloc.h"
#include"math.h"
#include "time.h"
#include "string.h"
#define MaxNumber 5
#define Num 100
#define deleted -1
#define Empty 0
#define full 1
typedef struct HashEntry Cell;
typedef struct Hashtbl * Hashtable;
struct HashEntry
{
    int Info;
    int mark;//标志单词或者前缀
    char *string;
    char *Prefix[MaxNumber];
};
struct Hashtbl
{
    int TableSize;
    Cell *TheCells; 
};

(2)查找函数

void IsinDirectory(int x_init,int y_init, char S[][4],Hashtable H)
{
        int direction[8] = {Left,Right,Up, Down, Left_Up,Right_Down,Left_Down,Right_Up};
        int Index;
        int Controldirection = 0;
        char temp[MaxNumber] = {'\0'};
    for (int i =0;i<=7;i++)
    {
        int x = x_init;
        int y = y_init;
        int j = 0;//控制单词的字符
        Controldirection = 0;
        memset(temp,'\0',sizeof(temp));
        while(x<=3&&x>=0&&y<=3&&y>=0)
        {
            temp[Controldirection++]= S[x][y]; 
            switch(direction[i])
            {
             case Left:
                 y--;
              break;
             case Right:
                 y++;
              break;
            case Up:
                x--;
                break;
            case Down:
                x++;
            break;
           case Left_Up:
               y--;
               x--;
            break;
          case Right_Down:
              x++;
              y++;
            break;
               case Left_Down:
               y--;
               x++;
            break;
               case Right_Up:
               y++;
               x--;
            break;
        }//switch
               //每次都要测试
              //首先测试该方向是否在前缀里面 
            temp[Controldirection]= '\0';
             Index = Find(H,temp);
            if(H->TheCells[Index].Info!=Empty)
            {  
                if(H->TheCells[Index].mark==1)//是单词
                printf("\n%s is in the dir, the location x is :%d, y is : %d",temp,x_init,y_init);
            }
            else
                break;//停止搜索该方向,因为没有对应前缀
        }//while(1)
    }// 换一个direction
    return;
}

(3)主函数

“`
int _tmain(int argc, _TCHAR* argv[])
{

char *p[] = {"this","two","fat","that","oai","tdg","\0"};

char S[][4] ={'t','h','i','s','w','a','t','s','o','a','h','g','f','g','d','t'};
Hashtable H = Initialize(50);
for(int i =0;*(p[i])!='\0';i++)
{
            int m = strlen(p[i]);
        for(int j = 0;j<=m-1;j++)
        {
            char *temp = (char*)malloc(sizeof(char)*(j+2));
            memset(temp,'\0',sizeof(char)*(j+2));
            memcpy(temp,p[i],(j+1)*sizeof(char));
            //插入单词x的所有前缀(prefix)与x本身
              Insert(H,temp,j==m-1?1:0);
        }
}
PrintTable(H);
    for (int i = 0;i<=3;i++)
{
    for (int j = 0;j<=3;j++)
        IsinDirectory(i,j,S,H);
}
return 0;

}
这里写图片描述

你可能感兴趣的:(利用散列结构查找字谜)