【数据结构与算法分析】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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值