1. 程式人生 > >【資料結構與演算法分析】1.2 編寫程式解決字謎問題

【資料結構與演算法分析】1.2 編寫程式解決字謎問題

原博: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;
}