不知道咕咕了多久,我已经记不起来多久没更新了,主要是嘿嘿嘿,妹子太好康了,看着看着就不想写了。嗯,今天就先跟新一点,以后保持活跃呀。
问题介绍
其实是一个挺常见的问题哈,就是大家经常在说说里看到的——一张图,然后说什么第一眼看到的三个单词将会带给你好运啥的(主要是有时候我找了半天也找不出三个像样的单词很气),我们要实现一个利用DFS查找单词的程序。
简单的思路
- 利用for循环来遍历每个节点,对该节点进行DFS
- 将当前的单词存储在单词栈内,判断该栈中的单词是否为单词或者是某单词的前缀
a.如果是单词,则输出一下,转b
b.如果是前缀,继续DFS
c.如果啥都不是,那么肯定就不是了,退出DFS
附代码
/**
* 解字谜游戏
* 输入:首先是一个 n*m 限制一下矩形的区域
* 输出:单词表中存在的所有单词
*/
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "words.txt" //这是单词表
#define MAX_WIDE 40 //最大的宽度
/* 全局变量 */
int row;//行数
int col;//列数
int dx[] = {1,-1,0,0}; //控制DFS移动
int dy[] = {0,0,1,-1};
int vis[MAX_WIDE][MAX_WIDE];//DFS标记
char wordsMap[MAX_WIDE][MAX_WIDE];
char curWords[20];
int lenth;
/* 键树的结构 */
typedef struct Node
{
char key;//关键字
struct Node* child; //孩子
struct Node* brother; //兄弟
int wordsTag; //标记是不是单词
}NODE;
typedef NODE* Tree;
/* 函数声明 */
void getInfo();//输入图
Tree buildNode(char c);//创建节点
Tree buildKeyTree();//建立键树
int isWords(Tree T);//查找
void DFS(int x,int y,Tree T);//搜索
void printWords();//打印
void addWords(Tree T,char s[]);//添加树节点
void showTree(Tree T);//展示树
int main()
{
Tree T = buildKeyTree();
// showTree(T);
getInfo();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
DFS(i,j,T);
return 0;
}
/* 函数声明 */
void getInfo()//输入图
{
scanf("%d %d",&row,&col);getchar();//后摇
for(int i=0;i<row;i++)
gets(wordsMap[i]);
printf("输入完成,请耐心等待查询结果\n");
}
Tree buildNode(char c)//创建节点
{
Tree tmp = (Tree)malloc(sizeof(NODE));
tmp->child = tmp->brother = NULL;
tmp->wordsTag = 0;
tmp->key = c;
return tmp;
}
void addWords(Tree T,char s[])//添加树节点
{
/* 先指向对应的键 */
while (T->brother != NULL && T->brother->key <= s[0])
T = T->brother;
/* 是否有这个值 */
if(T->key != s[0]) //无
{
Tree tmp = buildNode(s[0]);
tmp->brother = T->brother;
T->brother = tmp;
T=T->brother;
}
/* 单词读入,退出 */
if(s[1] == '\n' ||s[1] == '\0') //这主要是应为fgets的关系
{
T->wordsTag = 1;
return;
}
/* 该节点是否有孩子节点 */
if(T->child == NULL)
{
T->child = buildNode('a'); //这里先建立一个'a'节点方便进入
}
addWords(T->child,&s[1]);
}
Tree buildKeyTree()//建立键树
{
Tree T =buildNode('a');//树根
/* 建树 */
char s[20];
FILE *fp;
if((fp=fopen(FILE_NAME,"r"))==NULL)
{
printf("fail to open\n");
exit(0);
}
while ((fgets(s,20,fp)!= NULL))
{
addWords(T,s);
}
return T;
}
int isWords(Tree T)//查找
{
int i=0;
while (1)
{
/* 退出 */
if(T == NULL)
return 0;
/* 先指向当前的节点 */
while ( T->brother != NULL && T->key < curWords[i])
T = T->brother;
if(curWords[i] != T->key)
return 0;
if(++i==lenth)
break;
T = T->child;
}
// return T->wordsTag == 1? 1:2; //1表示这个是单词 2表示可能是单词 可能多次输出一个单词
if(T->wordsTag==1)
{
T->wordsTag = 0;
return 1;
}
else
return 2;
}
void DFS(int x,int y,Tree T)//搜索
{
/* 越界退出 || 被访问退出 */
if(x<0 || x>=row || y<0 || y>= col || vis[x][y])
return;
/* 对当前节点处理 */
vis[x][y] = 1; //标记
curWords[lenth++] = wordsMap[x][y]; //添加
int checkAns = isWords(T);
if(checkAns)
{
if(checkAns == 1)//如果是单词
printWords();
for(int i=0;i<4;i++)
DFS(x+dx[i],y+dy[i],T);
}
lenth--;
vis[x][y] = 0;
}
void printWords()//打印
{
for(int i=0;i<lenth;i++)
putchar(curWords[i]);
putchar('\n');
}
void showTree(Tree T)//展示树
{
/* 空退出 */
if(T==NULL)
return;
/* 加到单词栈 */
curWords[lenth++] = T->key;
if(T->wordsTag == 1)
printWords();
showTree(T->child);
lenth--;
showTree(T->brother);
}
传送门: 来我的博客玩耍呀!有单词表分享!!!
来源:CSDN
作者:憨皮烨
链接:https://blog.csdn.net/qq_43641752/article/details/103688869