來自:【數據結構與算法分析——C語言描述】練習1.2
問題描述:編寫一個程序求解字謎游戲問題。
書上給出了2種比較直觀的算法。
第一種:對單詞表中的每個單詞,我們檢查每一個有序三元組(行,列,方向),驗證是否有單詞存在。但壞處是這將導致大量嵌套的for循環。
第二種:對於每一個尚未進行到字謎最后的有序四元組(行,列,方向,字符數)我們可以測試所指的單詞是否在單詞表中。這也導致使用大量嵌套的for循環。如果在任意單詞中的最大字符數已知的情況下,那么該算法有可能節省一些時間。
上網看了幾位前輩的代碼,核心思想只有一個:暴力破解。看來for嵌套的命運逃不了了。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DICTSIZE 4 //字典內最大單詞數
#define WORDSIZE 21 //單詞最大長度 + 1
char puzzle[4][4] = {
{ 't', 'h', 'i', 's' },
{ 'w', 'a', 't', 's' },
{ 'o', 'a', 'h', 'g' },
{ 'f', 'g', 'g', 't' }
}; //字謎
char * dict[DICTSIZE] = { "this", "two", "fat", "that" }; //字典
int wordExist(int x, int y, int dir, int maxChars, char * retWord);
int main(void)
{
char word[WORDSIZE];
for (int i = 0; i < 4; i++) //行
{
for (int j = 0; j < 4; j++) //列
{
for (int d = 0; d < 8; d++) //方向
{
for (int n = 1; n <= 4; n++) //最大字符數
{
if (wordExist(i, j, d, n, word))
{
printf("%s\n", word);
break;
}
}
}
}
}
system("pause");
return 0;
}
/*
查找是否有單詞存在
如果有,將找到的第一個單詞寫入retWord
查找位置(x, y),方向dir
*/
int wordExist(int x, int y, int dir, int maxChars, char * retWord)
{
char str[WORDSIZE];
int ct = 0;
int k = 0;
for (int i = 0; i < maxChars; i++)
{
//添加(x, y)處的一個字符
str[ct] = puzzle[x][y];
str[ct + 1] = '\0';
//拿str到字典內遍歷
for (int j = 0; j < DICTSIZE; j++)
{
if (strcmp(str, dict[j]) == 0)
{
strcpy(retWord, dict[j]);
return 1;
}
}
ct++;
//確定下一個字符位置(x,y)
switch (dir)
{
case 0: //從左到右
y++;
break;
case 1: //從右到左
y--;
break;
case 2: //從上到下
x++;
break;
case 3: //從下到上
x--;
break;
case 4: //從左上到右下
x++;
y++;
break;
case 5: //從右下到左上
x--;
y--;
break;
case 6: //從右上到左下
x--;
y++;
break;
case 7: //從左下到右上
x++;
y--;
break;
default:
puts("Direction error.");
return 0;
}
}
return 0;
}
輸出:

算法簡單粗暴,適合算法初學。如果您有更好的算法,歡迎交流。與前輩和愛好者學習是我的榮幸。謝謝!
參考鏈接:
