原博:http://blog.csdn.net/u013667086/article/details/49179741
问题描述:
从已知的字谜中找出在字典中的单词
解决思路:
1、用指针数组存放字谜和字典单词
2、将字典单词排序并加上hash索引
3、遍历字谜,每一个在字典中有的字母按八个方向进行遍历找出单词(将字典单词遍历完了就代表有)
4、即使是参考其他人写的,自己写出来也有好多问题,果然编码能力不行啊
算法实现:
#include<stdio.h>
#include<stdlib.h>
int compare(char *word1, char *word2);
void sort(char **dict,int m);
void makeIndex(char **dict);
char **findWord(char **riddle,int n,char **dict,int m,int *size);
char **findWordImpl(char **riddle,int row,int col,int n,int index,char **dict,int m,int *size);
char hash[26];
int main() {
//字典数据,简便起见,就四个
char *word1 = "that";
char *word2 = "this";
char *word3 = "fat";
char *word4 = "two";
char *dict[4];
dict[0] = word1;
dict[1] = word2;
dict[2] = word3;
dict[3] = word4;
//字谜数据
char letter1[4] = {'t','h','a','t'};
char letter2[4] = {'w','a','t','s'};
char letter3[4] = {'o','a','h','g'};
char letter4[4] = {'f','g','d','t'};
char *riddle[4];
riddle[0] = letter1;
riddle[1] = letter2;
riddle[2] = letter3;
riddle[3] = letter4;
//将字典单词按首字母排序
sort(dict,4);
//将排好序的单词按首字母加上索引
makeIndex(dict);
//遍历字谜查找单词
int size,i;
char **result = findWord(riddle,4,dict,4,&size);
for(i=0;i<size;i++){
printf("%s\n",result[i]);
}
}
void sort(char **dict,int m) {
int i,j;
for(i=0;i<m-1;i++)
for(j=i+1;j<m;j++){
if(compare(dict[i],dict[j])){
char *temp = dict[i];
dict[i] = dict[j];
dict[j] = temp;
}
}
}
int compare(char *word1,char *word2) {
int index1=0,index2=0;
while(word1[index1]&&word2[index2]){
if(word1[index1]>word2[index2])
return 1;
else if (word1[index1]<word2[index2])
return 0;
index1++;
index2++;
}
if(word1[index1])
return 1;
return 0;
}
void makeIndex(char **dict) {
int i,j;
char temp;
for(i=0;i<26;i++){
hash[i] = -1;
}
for(j=0;j<4;j++){
temp = dict[j][0];
if(hash[temp-'a'] == -1){
hash[temp - 'a'] = j;//表示ascii码是它的字符
}
}
}
char **findWord(char **riddle,int n,char **dict,int m,int *size) {
int row,col;
int count=0;
char temp,index;
char **res = (char**)malloc(sizeof(char*)*m);//不在堆上分配返回就被销毁了
for(row=0;row<n;row++)
for(col=0;col<n;col++){
temp = riddle[row][col];
index = hash[temp - 'a'];
if(index == -1)
continue;
int size;
char **result = findWordImpl(riddle,row,col,4,index,dict,4,&size);
//以一个字母开头的八个方向都有可能有单词
if(size){
int i;
for(i=0;i<size;i++)
res[count++]=result[i];
}
}
*size = count;
return res;
}
char **findWordImpl(char **riddle,int row,int col,int n,int index,char **dict,int m,int *size) {
char **res = (char **)malloc(sizeof(char*)*m);
int count = 0;
int dir;
int i;
char head = riddle[row][col];
int tmpRow,tmpCol;
int directIndex;
for(dir = 1;dir<=8;dir++){
directIndex = 0;
tmpRow = row;
tmpCol = col;
switch (dir)
{
case 1://左到右
for(i = index;i<m&&dict[i][0]==head;i++){//相同字母开头的可能有多个
while(dict[i][directIndex]&&tmpCol<n){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpCol++;
directIndex++;
}
if(!dict[i][directIndex]){//字典中该单词最后位置了
res[count++] = dict[i];
break;
}
}
break;
case 2://从右向左
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpCol>=0){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpCol--;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 3://从上到下
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpRow<n){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow++;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 4://从下到上
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpRow>=0){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow--;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 5://从左下到右上
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpCol<n&&tmpRow>=0){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow--;
tmpCol++;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 6://从左上到右下
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpCol<n&&tmpRow<n){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow++;
tmpCol++;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 7://从右下到左上
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpCol>=0&&tmpRow>=0){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow--;
tmpCol--;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
case 8://从右上到左下
for(i = index;i<m&&dict[i][0]==head;i++){
while(dict[i][directIndex]&&tmpCol>=0&&tmpRow<n){
if(dict[i][directIndex]!=riddle[tmpRow][tmpCol]){
break;
}
tmpRow++;
tmpCol--;
directIndex++;
}
if(!dict[i][directIndex]){
res[count++] = dict[i];
break;
}
}
break;
default:
break;
}
}
*size = count;
return res;
}