华为编程大赛——路径查找

l  问题描述

给定N*N字母矩阵,从任意点出发,上,下,左,右移动,在规定方向连续匹配给定的单词序列。即称为命中,否则不命中,
字符矩阵中的字母仅能使用一次,不能在同一单元格停留两次。字符矩阵最大50*50,都为大写字母。
输入1为字母矩阵,输入2为字母序列,输出是否匹配。

 要求实现函数
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’

2. 示例

输入:"ABCFEDGHI", 3, "ABCDEFGHI"
返回:1 

输入:"ABCFEDGAI", 3, "ABCDEA"

返回:1


输入: "ABABABABABABABABABABABABA", 5, "ABABABBA"
返回: 0

输入: "AAAA", 2, "AAAA"

返回:1


预备知识:

在C语言中 strchr 和 strstr函数都被包含在<string.h>头文件中,
也就是要调用它们时要在程序前面包含<string.h>头文件,也就是写这个语句:

strchr函数原型:char * strchr(char * str, int ch);
功能就是找出在字符串str中第一次出项字符ch的位置,找到就返回该字符位置的指针(
也就是返回该字符在字符串中的地址的位置),找不到就返回空指针(就是 null)。


strstr 函数原型: char * strstr(char * str1,char * str2);
功能就是找出在字符串str1中第一次出项字符串str2的位置(也就是说字符串sr1中要包含有字符串str2),
找到就返回该字符串位置的指针(也就是返回字符串str2在字符串str1中的地址的位置),找不到就返回空指针(就是 null)。


它们一个是求一个字符在字符串中得位置,另一个是求一个字符串在另一个字符串中的位置。


思路:路径查找问题依然是一个回溯法,注意两点:

1. 尝试过的位置如果不合适,要回溯回来。
2. 如果一个字符串检测完毕,需要将visited复位,以作下一次的尝试。

#include<iostream>
using namespace std;

int visited[50][50]={0};

int dfs(const char *Map, unsigned int iArrN, const char *PathStr, int row, int column){

	if (*PathStr=='\0'){//结束条件
		return 1;
	}


	//以(row,column)为起点,上、下、左、右 查找。

	//向上
	if(row>0 && !visited[row-1][column] && Map[(row-1)*iArrN + column]==*PathStr){

		visited[row-1][column]=1;//回溯
		if(
			dfs(Map, iArrN, PathStr+1, row-1, column)==1
		)
			return 1;
		else
			visited[row-1][column]=0;//回溯
	}

	//向下
	if( row<iArrN-1 && !visited[row+1][column] && Map[(row+1)*iArrN + column]==*PathStr ){

		visited[row+1][column]=1;
		if(
			dfs(Map, iArrN, PathStr+1, row+1, column)==1
		)
			return 1;
		else
			visited[row+1][column]=0;//
	}
	
	//向左
	if( column>0 && !visited[row][column-1] && Map[row*iArrN + column-1]==*PathStr ){
		visited[row][column-1]=1;
		if(
			dfs(Map, iArrN, PathStr+1, row, column-1)==1
		)
			return 1;
		else 
			visited[row][column-1]=0;
	}

	//向右
	if(column<iArrN-1 && !visited[row][column+1] && Map[row*iArrN + column+1]==*PathStr ){
		visited[row][column+1]=1;
		if(
			dfs(Map, iArrN, PathStr+1, row, column+1)==1
		)
			return 1;
		else 
			visited[row][column+1]=0;
	}

	return 0;
		
}

int FindStat(const char *Map, unsigned int iArrN, const char *PathStr){

	const char *pos=Map;
	int location,row,column;

	while( (pos=strchr(pos,*PathStr)) != NULL ){//寻找入口
		
		location=pos-Map;
		row=location / iArrN;//将要尝试的列
		column=location % iArrN;//将要尝试的行
		
		visited[row][column]=1;
		if (1==dfs(Map,iArrN,PathStr+1,row,column)){

			//记得visited是一个公共的数组,上一个用过之后需要将其复位------出bug
			for(int i=0;i<50;++i)
				for(int j=0;j<50;++j)
					visited[i][j]=0;
			return 1;
		}
		visited[row][column]=0;
		++pos;
	}

	//记得visited是一个公共的数组,上一个用过之后需要将其复位------出bug
	for(int i=0;i<50;++i)
		for(int j=0;j<50;++j)
			visited[i][j]=0;

	//执行到这里说明不存在,需要返回0
	return 0;
}


int main()
{
	char *Map[3]={"ABCFEDGAI","ABCFEDGHI","ABABABABABABABABABABABABA"};
	char *PathStr[3]={"ABCDEA","ABCDEFGHI","ABABABBA"};
	int  iArrN[3]={3,3,5};
	for(int i=0;i<3;++i){
		printf("%d\n",FindStat(Map[i],iArrN[i],PathStr[i]));
	}

	return 0;
}


posted @ 2014-07-22 21:33  StevenSuo  阅读(218)  评论(0编辑  收藏  举报