摘要:曾经我们用最基本的查找方法查找过字谜问题,如果字谜用二维数组存放(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;