最近做一个东西正好需要生成字典的算法,类似一些密码字典生成器(主要运用在暴力破解)。生成的密码会根据密码长度与字典集合的长度成指数关系。
       可以用一个函数来表示
        f( x , y  )  = x ^y ;           x表示我们要生产的密码长度,y表示我们要生成的密码字典字符集合。
      当时想到就有3个算法。
      
    1.循环
         关于循环,可以参考水仙花数的多层嵌套求解,主要算法如下:
 1
/**//// Dict 为生成的密码 , g_Dict为字典集合 2
for ( int i = 0 ; i < Len  ; i++ )
 3

{
 4
    Dict[0] = g_Dict[i];
 5
 6
    for ( int j = 0 ; j < Len ; j++)
 7
    
{
 8
        Dict[1] = g_Dict[j];
 9
10
        for ( int k = 0 ; k < Len ; k++ )
11
        
{
12
            Dict[2] = g_Dict[k];
13
14
            /**//*
15
            *    几位密码就嵌套几层循环
16
            */
17
18
        }
19
    }
20
} 
       这种方式移植不好,而且代码臃肿。
    2.递归
       做过字符串的全排列的都明白这个算法,这种也是基于这种方式:但是由于随着字典集合或者密码长度的增加,很容易会出现堆栈的内存溢出。
      
 1
void solve(int len,int p , int s,int n)
 2

{
 3
    int i;    
 4
    if( s == n )
 5
    
{    
 6
        /**////std::cout << Dict << std::endl;
 7
        return ;
 8
    }    
 9
    if(s>n||p>n)
10
        return;    
11
    for( i=p ; i < len ; i++ )    
12
    
{    
13
        solve(len,i+1,s+1,n);    
14
    }
15
} 
    3.BFS
       有了前2种方法的不错,然后写了一个非递归的算法
        主要借用横向扫描的方式,借鉴一个数组来进行记录当前应该生成的密码。
       主要算法如下:
        
 1
/**//*
 2
*    生成字典的函数       
 3
*     @parm  需要生成的长度          
 4
*/
 5
void    MakeDict( int Len )
 6

{
 7
    char    Dict[MaxDictLen+1];            // 生成的字典字符串
 8
    int        Array[MaxDictLen];            // 记录当前应该生成字典数组
 9
10
    memset( Array , 0  , sizeof(Array) );
11
12
    bool    bStop =  true;
13
14
    int        i,j;
15
    for ( ; bStop ; )                    // 是否生成完毕
16
    
{
17
        for ( i = 0 ; i < Len ; i++ )
18
        
{
19
            Dict[i] = g_Dict[Array[i]];
20
        }
21
        Dict[Len] = '\0';
22
23
        std::cout << Dict << std::endl;
24
25
        /**//// 字典数组坐标更新
26
        for ( j = Len - 1  ;  j >= 0 ;  j -- )        
27
        
{
28
            Array[j] ++ ;
29
30
            if ( Array[j] != ((int)g_Dict.length()) )
31
            
{ 
32
                break;
33
            }
34
            else
35
            
{
36
                Array [j] = 0;
37
                if( j == 0 )            // 生成完毕
38
                    bStop = false;    
39
            }
40
        }
41
    }
42
} 
附上第三个生成算法源码:
link