不知道这是哪一届的最后一题,捣腾一下,见笑。。。
3、路径查找(50分)
l 问题描述
给定N*N字母矩阵,从任意点出发,上,下,左,右移动,在规定方向连续匹配给定的单词序列。即称为命中,否则不命中,字符矩阵中的字母仅能使用一次,不能在同一单元格停留两次。字符矩阵最大50*50,都为大写字母。输入1为字母矩阵,输入2为字母序列,输出是否匹配。
l 要求实现函数
int FindStat(const char *Map, unsigned int iArrN, const char *PathStr)
【输入】Map: 给定的字母矩阵
iArrN: 字母矩阵的行数
PathStr: 给定的字母序列
【输出】无
【返回】是否能找到命中的单词序列,命中返回1,否则返回0
注:输入矩阵是以一维形式保存的二维数组,
比如输入为{‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’,’G’, ‘H’, ‘I’},
实际上表示如下3*3的矩阵
‘A’,’B’,’C’,
‘D’,’E’,’F’,
‘G’,’H’,’I’
l 示例
输入:"ABCFEDGHI", 3, "ABCDEFGHI"
返回:1
输入:"ABCFEDGAI", 3, "ABCDEA"
返回:1
输入: "ABABABABABABABABABABABABA", 5, "ABABABBA"
返回: 0
输入: "AAAA", 2, "AAAA"
返回:1
#include <cstdio>
#include <cstring>
#include <cstdlib>
int flag = 0;
#define MAXN 50
int if_vis[MAXN*MAXN];
void dfs(const char *Map, char *start,unsigned int iArrN,char *cur, const char *PathStr,int *if_vis);
int FindStat(const char *Map, unsigned int iArrN, const char *PathStr);
int main()
{
const char *Map = "ABABABABABABABABABABABABA";
const char *PathStr = "ABABABBA";
unsigned int iArrN = 5;
printf("\n%d\n",FindStat(Map, iArrN, PathStr));
return 0;
}
void dfs(const char *Map,char *start, unsigned int iArrN, char *cur,const char *PathStr,int *if_vis)
{
int pos = start - (char *)Map;
if(!if_vis[pos])//若访问过,则返回
if_vis[pos] = 1;
else
return;
if((cur - PathStr) == (strlen(PathStr)-1))
{
flag = 1;
return;
}
//上
int up = pos - iArrN;
if(up >= 0 && !if_vis[up])
{
if(Map[up] == *(++cur))
{
dfs(Map,start-iArrN,iArrN,cur,PathStr,if_vis);
if(flag)
return;
else
{
if_vis[up] = 0;
cur--;
}
}
else
{
cur--;
}
}
//下
int down = pos + iArrN;
if(down <= iArrN*iArrN-1 && !if_vis[down])
{
if(Map[down] == *(++cur))
{
dfs(Map,start+iArrN,iArrN,cur,PathStr,if_vis);
if(flag)
return;
else
{
if_vis[down] = 0;
cur--;
}
}
else
{
cur--;
}
}
//左
if(pos%iArrN > 0)
{
int left = pos -1;
if(left >= 0 && !if_vis[left])
{
if(Map[left] == *(++cur))
{
dfs(Map,start-1,iArrN,cur,PathStr,if_vis);
if(flag)
return;
else
{
if_vis[left] = 0;
cur--;
}
}
else
{
cur--;
}
}
}
//右
if(pos%iArrN < iArrN)
{
int right = pos +1;
if(right <= iArrN*iArrN-1 && !if_vis[right])
{
if(Map[right] == *(++cur))
{
dfs(Map,start+1,iArrN,cur,PathStr,if_vis);
if(flag)
return;
else
{
if_vis[right] = 0;
cur--;
}
}
else
{
cur--;
}
}
}
}
int FindStat(const char *Map, unsigned int iArrN, const char *PathStr)
{
char *start, *tmp = (char *)Map,*cur = (char *)PathStr;
while((start= strchr(tmp,PathStr[0])) != NULL)
{
if(flag)
break;
tmp = start+1;
memset(if_vis,0,(iArrN*iArrN-1)*sizeof(int));
dfs(Map,start,iArrN,cur,PathStr,if_vis);
for(int i=0;i < iArrN*iArrN;i++)
{
printf("%d ",if_vis[i]);
if(!((i+1)%iArrN))
printf("\n");
}
printf("\n");
}
return flag;
}
思想,从第一个和要匹配子串的首字母相同的位置开始遍历矩阵。。。。。还是比较容易看懂。。。。