• 广度优先搜索算法


    华容道游戏是非常经典的BFS应用的题目。

    下面是几个我参考过的链接:

    使用java语言实现,充分体现OOAD和数据结构的应用,讲的非常详细,但是太过于复杂了:

    http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html

    简单版本的介绍,非常有用,而且有完整的源代码:

    http://blog.chinaunix.net/u/19651/showart_395172.html

    虽然讲的详细,但是代码也成这副样子,值得同情:

    http://www.fjptsz.com/xxjs/xjw/rj/110.htm

    下面是我通过这道题的一些体会:

    1、重复状态的判重方法

    在很多与走步有关的题目中,一般会涉及到重复状态的检测,在搜索过程中需要忽略掉这些重复状态,这样才能避免不必要的搜索代价。

    我使用通过对局面做hash的方法来检测是否存在重复状态,只有不重复的新状态才插入到hash表中。原来hash函数是通过对grid[5][4]这个局面进行移位运算来产生分布均匀的hash值,但是效果始终不理想。

    int getHashValue(char grid[5][4]) {
    	
    	int mask13=0x0001fff;		//低位连续的13个1 
    	int mask19=0x007ffff;		//低位连续的19个1 
    	
    	int result=0,tmp;
    	for(int i=0;i<5;i=i+2){
    	
    		tmp=(grid[i][0]<<24) | (grid[i][1]<<16) | (grid[i][2]<<8) | (grid[i][3]);
    		result += (((tmp & (mask13<<13))>>13) | ((tmp & mask19)<<19));
    		result ^=(grid[i+1][0]<<24) | (grid[i+1][1]<<16) | (grid[i+1][2]<<8) | (grid[i+1][3]);
    		
    	}
        result= (result<=0)? -result: result;
        
    	return result%HashTableSize;	//最后一定要对HashTable取余 
    }


     

    后来我发现可以将局面转化为字符串的形式,然后对字符串进行hash处理,这样得到的hash函数效果非常好,因为本身对string就有一个很好的hash函数

    int getHashValue(char grid[5][4]) {
    	
    	char* grid_begin= &grid[0][0];
    	char* grid_end= &grid[5][0];
    	string str(grid_begin , grid_end) ;
    	
    	
    	int result=0 ;
    	for( int i=0 ; i<str.length() ; i++)
    		result = 37* result + str[i];
    		
    	result = result % HashTableSize ;
    	
    	if( result <0 )
    		result += HashTableSize ;
    		
    	return result ;
    	
    	
    }


     

    注意string类型hash函数的写法,如果在取余操作后,result的值小于0,那么还要加上HashTableSize的值

    通过这个hash函数:

    1、C++中如何将字符数组转化为字符串呢?

    利用string类的构造函数

    string类的主要几个构造函数为:

    string();
      string( size_type length, char ch );
      string( const char *str );
      string( const char *str, size_type length );
      string( string &str, size_type index, size_type length );
      string( input_iterator start, input_iterator end );


     

    下面我给出几个测试例子:

    #include<iostream>
    #include<string>
    using namespace std;
    
    int main(){
    	
    	
    	char init_grid[5][4]={				
    	'v','c','0','v',/
    	'0','0','0','0',/
    	'v','h','0','v',/
    	'0','s','s','0',/
    	's','b','b','s'
    	};
    	
    	char* grid_begin=&init_grid[0][0];		//通过首末指针来调用构造函数
    	char* grid_end = &init_grid[5][0];
    	string str(grid_begin,grid_end);
    	cout<<str<<endl;
    	
    	char a[5]={
    		'h','e','e','o','p'
    	};
    	
    	//调用string的构造函数:string( const char *str ); 
    	string str1(a,a+5);						//对于一维数组可以使用指针的思想
    	cout<<str1<<endl;
    
    	const char* b="hello";					//直接使用const char*参数调用构造函数
    	string str2(b);
    	cout<<str2<<endl;
    	
    	return 0;
    	
    }


     

    可以看到这巧妙的使用第四个构造函数:string( input_iterator start, input_iterator end )

    对于C++中的内置类型数据迭代器对应的其实就是指针,在这个例子中grid二维数组的末指针可以为 &grid[4][5],也可以是grid[5][0].

     这里如果直接使用string的第二构造函数  string( const char *str ); 并以 &grid[0][0]作为参数,获得的string对象中是有乱码的。

    2、保证hash表的大小为素数

    当hash表的大小为素数时,可以减少冲突的发生可能性。下面是一个获取某个数的下一个素数的测试程序:

    #include<iostream>
    #include<cstdio>
    #include<fstream>
    using namespace std;
    
    bool isPrime(unsigned int a){
    	
    	if( a==2 || a == 3)
    		return true ;
    		
    	if( a==1 || a%2 == 0 )
    		return false ;
    		
    	for(int i=3 ; i*i<=a ; i+=2){
    		
    		if( a % i == 0)
    			return false ;		
    	}
    	
    	return true ;
    }
    
    int nextPrime(unsigned int a){
    	
    	if( a % 2 == 0)
    		a++;
    		
    	for( ; !isPrime(a) ; a+=2) ;
    	
    	return a ;
    }
    
    int main(int argc,char* argv[]) {
    	
    	
    	cout<<nextPrime(1<<18)<<endl;
    	
    	return 0;
    
    }

    转载文章出处:http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5850715

  • 相关阅读:
    IfcDescriptiveMeasure
    IfcBooleanOperator
    IfcKnotType
    IfcCurveOnSurface
    IfcCurvatureMeasure
    IfcBSplineCurveForm
    IfcDoseEquivalentMeasure
    netty系列之:使用UDP协议
    netty系列之:自定义编码和解码器要注意的问题
    netty系列之:内置的Frame detection
  • 原文地址:https://www.cnblogs.com/yangzhi/p/3576642.html
Copyright © 2020-2023  润新知