【資料結構與演算法分析1.2】編寫一個程式求解字謎遊戲問題
阿新 • • 發佈:2019-02-19
問題描述:輸入是由一些字母和單詞構成的二維陣列,目標是找出字謎中的單詞,這些單詞可以是水平、垂直或沿對角線以任何方向放置。找出二維陣列中所有的單詞
寫完這個程式,手都要斷掉了,太TM麻煩了,而且效率很低,到底有多少個for迴圈,自己都數不清。
//1.2編寫一個程式求解字謎遊戲問題
#include <iostream>
using namespace std;
/**
directions:
1------從左到右
2------從右到左
3------從上到下
4------從下到上
5------從左下到右上
6------從左上到右下
7------從右下到左上
8------從右上到左下
*/
int compare(char *word1,char *word2){
int index1=0,index2=0;
while(word1[index1]&&word2[index2]){
if(word1[index1]<word2[index2])
return 0;
else if(word1[index1]>word2[index2])
return 1;
index1++;
index2++;
}
if(word1[index1])
return 1;
else
return 0;
}
//對字典進行排序,冒泡法
void sort(char **direc,int m){
int i,j;
char* word1;
char* word2;
for(i = m;i>0;i--){
for(j = 0;j<i-1;j++){
word1 = direc[j];
word2 = direc[j+1];
if(compare(word1,word2)){//word1>word2
direc[j] = word2;
direc[j+1 ] = word1;
}
}
}
}
char **findOne(char **puzzle,int row,int col,int n,char **direct,int m,int index,int *returnSize){
char **res = (char **)malloc(sizeof(char*)*m);
int count = 0;
int dir;
int i;
char head = puzzle[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&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol<n){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpCol++;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 2://從右向左
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol>=0){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpCol--;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 3://從上到下
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpRow<n){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow++;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 4://從下到上
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpRow>=0){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow--;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 5://從左下到右上
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol<n&&tmpRow>=0){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow--;
tmpCol++;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 6://從左上到右下
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol<n&&tmpRow<n){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow++;
tmpCol++;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 7://從右下到左上
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol>=0&&tmpRow>=0){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow--;
tmpCol--;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
case 8://從右上到左下
for(i = index;i<m&&direct[i][0]==head;i++){
while(direct[i][directIndex]&&tmpCol>=0&&tmpRow<n){
if(direct[i][directIndex]!=puzzle[tmpRow][tmpCol]){
break;
}
tmpRow++;
tmpCol--;
directIndex++;
}
if(!direct[i][directIndex]){
res[count++] = direct[i];
break;
}
}
break;
default:
break;
}
}
*returnSize = count;
return res;
}
char **findWord(char **puzzle,int n,char **direc,int m,int *returnSize){
char **res = (char **)malloc(sizeof(char *)*m);//返回值
int count = 0;//res index
int row,col;
int i;
char tmp;
char hash[26];//store first word
char index;
sort(direc,m);//將direct排序
for(i = 0;i<26;i++)
hash[i] = -1;
for(i = 0;i<m;i++){
tmp = direc[i][0];
if(hash[tmp-'a']==-1)
hash[tmp-'a'] = i;//儲存direc的開始索引
}
//print direc and hash table
//for(i = 0;i<m;i++)
// printf("%s\n",direc[i]);
//for(i = 0;i<26;i++)
// printf("%d ",hash[i]);
for(row = 0;row<n;row++){
for(col = 0;col<n;col++){
tmp = puzzle[row][col];
//check hash table;
index = hash[tmp-'a'];
if(index==-1)
continue;
int size;
char **word = findOne(puzzle,row,col,n,direc,m,index,&size);
if(size){
for(i = 0;i<size;i++)
res[count++] = word[i];
}
}
}
*returnSize = count;
return res;
}
int main(){
int n = 4;
char *puzzle[4];
char p1[4] = {'t','h','i','s'};
char p2[4] = {'w','a','t','s'};
char p3[4] = {'o','a','h','g'};
char p4[4] = {'f','g','d','t'};
puzzle[0] = p1;
puzzle[1] = p2;
puzzle[2] = p3;
puzzle[3] = p4;
char *s1 = "this";
char *s2 = "two";
char *s3 = "otw";
char *s4 = "fat";
char *s5 = "that";
char *s6 = "hello";
char *s7 = "fuck";
char *direc[7];
direc[0] = s1;
direc[1] = s2;
direc[2] = s3;
direc[3] = s4;
direc[4] = s5;
direc[5] = s6;
direc[6] = s7;
int size;
char ** res = findWord(puzzle,4,direc,7,&size);
int i;
for(i = 0;i<size;i++)
printf("%s\n",res[i]);
system("pause");
}