【資料結構與演算法分析】1.2 編寫程式解決字謎問題
阿新 • • 發佈:2019-01-23
原博: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; }