http://blog.csdn.net/zxasqwedc/article/details/42270215

permutation的程式码都会长成这样的格式:

  ] = { 'a', 'b', 'c' };     //字串,需要先由小到大排序过
  ];    //用来存放一组可能的答案
  ];        //纪录该字母是否使用过,用过为true

 void  permutation ( int  k ,  int  n )
 {
     // it's a solution
     if  ( k  ==  n )
     {
          ;  i < n ;  i ++)
             cout  <<  solution [ i ];
         cout  <<  endl ;
         return ;                  // if-else改成return
     }

     // 针对solution[i]这个位置,列举所有字母,并各自递回
      ;  i < n ;  i ++)
         if  (! used [ i ])
         {
             used [ i ] =  true ;

             solution [ k ] =  s [ i ];  //填入字母
             permutation ( k +  ,  n );

             used [ i ] =  false ;
         }
 }

字串排列

有个常见的问题是:列出字串abc的所有排列,要依照字典顺序列出。其实这就跟刚才介绍的东西大同小异,只要稍加修改程式码即可。

  ] = { 'a', 'b', 'c' };     //字串,需要先由小到大排序过
  ];    //用来存放一组可能的答案
  ];        //纪录该字母是否使用过,用过为true

 void  permutation ( int  k ,  int  n )
 {
     if  ( k  ==  n )  // it's a solution
     {
          ;  i < n ;  i ++)
             cout  <<  solution [ i ];
         cout  <<  endl ;
     }
     else
     {
         // 针对solution[i]这个位置,列举所有字母,并各自递回
          ;  i < n ;  i ++)
             if  (! used [ i ])
             {
                 used [ i ] =  true ;

                 solution [ k ] =  s [ i ];  //填入字母
                 permutation ( k +  ,  n );

                 used [ i ] =  false ;
             }
     }
 }
  ] = { 'a', 'b', 'c' };     //字串,需要先由小到大排序过
  ];    //用来存放一组可能的答案
  ];        //纪录该字母是否使用过,用过为true

 void  permutation ( int  k ,  int  n )
 {
     // it's a solution
     if  ( k  ==  n )
     {
          ;  i < n ;  i ++)
             cout  <<  solution [ i ];
         cout  <<  endl ;
         return ;                  // if-else改成return
     }

     // 针对solution[i]这个位置,列举所有字母,并各自递回
      ;  i < n ;  i ++)
         if  (! used [ i ])
         {
             used [ i ] =  true ;

             solution [ k ] =  s [ i ];  //填入字母
             permutation ( k +  ,  n );

             used [ i ] =  false ;
         }
 }

避免重复排列

若是字串排列的问题改成:列出abb的所有排列,依照字典顺序列出。答案应该为abb、aba、baa。不过使用刚刚的程式码的话,答案却会变成这样:

abb
abb
bab
bba
bab
bba

这跟预期的不一样。会有这种结果,是由于之前的程式有个基本假设:字串中的每个字母都不一样。尽管出现了一样的字母,但是程式还是把它当作是不一样的字母,依旧把所有可能的排列都列出,也就是现在的结果──有一些排列重复出现了。

要解决问题,在列举某一个位置的字母时,就必须避免一直填入一样的字母。如此就可以避免产生重复的排列。

  ] = { 'a', 'b', 'b' };     //字串,需要先由小到大排序过
  ];
  ];

 void  permutation ( int  k ,  int  n )
 {
     if  ( k  ==  n )
     {
          ;  i < n ;  i ++)
             cout  <<  solution [ i ];
         cout  <<  endl ;
         return ;
     }

     char  last_letter  =  '\0' ;
      ;  i < n ;  i ++)
         if  (! used [ i ])
             if  ( s [ i ] !=  last_letter )     //避免列举一样的字母
             {
                 last_letter  =  s [ i ];      //纪录刚才使用过的字母
                 used [ i ] =  true ;

                 solution [ k ] =  s [ i ];
                 permutation ( k +  ,  n );

                 used [ i ] =  false ;
             }
 }

因为输入的字串由小到大排序过,字母会依照顺序出现,所以只要检查上一个使用过的字母,判断一不一样之后,就可以避免列举一样的字母了。

程式码也可以改写成这种风格:

  ] = { 'a', 'b', 'b' };     //字串,需要先由小到大排序过
  ];
  ];

 void  permutation ( int  k ,  int  n )
 {
     if  ( k  ==  n )
     {
          ;  i < n ;  i ++)
             cout  <<  solution [ i ];
         cout  <<  endl ;
         return ;
     }

     char  last_letter  =  '\0' ;
      ;  i < n ;  i ++)
     {                            // if not改成continue
         if  ( used [ i ])  continue ;
         if  ( s [ i ] ==  last_letter )  continue ;   //避免列举一样的字母

         last_letter  =  s [ i ];      //纪录刚才使用过的字母
         used [ i ] =  true ;

         solution [ k ] =  s [ i ];
         permutation ( k +  ,  n );

         used [ i ] =  false ;
     }
 }

http://www.cnblogs.com/guxuanqing/p/5602028.html

backtracking(回溯算法)的更多相关文章

  1. Java求解迷宫问题:栈与回溯算法

    摘要: 使用栈的数据结构及相应的回溯算法实现迷宫创建及求解,带点JavaGUI 的基础知识. 难度: 中级 迷宫问题是栈的典型应用,栈通常也与回溯算法连用. 回溯算法的基本描述是: (1)  选择一个 ...

  2. 回溯算法——解决n皇后问题

    所谓回溯(backtracking)是通过系统地搜索求解问题的方法.这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易. 不多说,放上n皇后的回溯问题代码 ...

  3. LeetCode通关:连刷十四题,回溯算法完全攻略

    刷题路线:https://github.com/youngyangyang04/leetcode-master 大家好,我是被算法题虐到泪流满面的老三,只能靠发发文章给自己打气! 这一节,我们来看看回 ...

  4. 46. Permutations 回溯算法

    https://leetcode.com/problems/permutations/ 求数列的所有排列组合.思路很清晰,将后面每一个元素依次同第一个元素交换,然后递归求接下来的(n-1)个元素的全排 ...

  5. ACM/ICPC 之 最长公共子序列计数及其回溯算法(51Nod-1006(最长公共子序列))

    这道题被51Nod定为基础题(这要求有点高啊),我感觉应该可以算作一级或者二级题目,主要原因不是动态规划的状态转移方程的问题,而是需要理解最后的回溯算法. 题目大意:找到两个字符串中最长的子序列,子序 ...

  6. c语言数据结构:递归的替代-------回溯算法

    1.要理解回溯就必须清楚递归的定义和过程. 递归算法的非递归形式可采用回溯算法.主要考虑的问题在于: 怎样算完整的一轮操作. 执行的操作过程中怎样保存当前的状态以确保以后回溯访问. 怎样返回至上一次未 ...

  7. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  8. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...

  9. 回溯算法之n皇后问题

    今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...

随机推荐

  1. SQLite 数据库调研

    SQLite数据库的特点(转载的): ★技术上的优点和特性 SQLite是一个轻量级.跨平台的关系型数据库.既然号称关系型数据库,支持SQL92标准中常用的玩意儿(比如视图.事务.触发器等)就是理所当 ...

  2. 12个Linux进程管理命令介绍

    导读 执行中的程序称作进程.当程序可以执行文件存放在存储中,并且运行的时候,每个进程会被动态得分配系统资源.内存.安全属性和与之相关的状态.可以有多个进程关联到同一个程序,并同时执行不会互相干扰.操作 ...

  3. statusbar 样式

    1:statusBar字体为白色 在plist里面设置View controller-based status bar appearance 为 NO:设置statusBarStyle 为 UISta ...

  4. 跟着百度学PHP[4]OOP面对对象编程-15-魔术方法__call方法

    简而言之就是调用了一个类中没有的方法就会自动调用__call()方法, 该参数有两个必须的参数! 第一个参数:调用的不存在的方法的方法名. 第二个参数:调用不存在的方法的参数. 但是总的说回来,__c ...

  5. Python自动化装饰器问题解疑

    问题一 到底是怎么执行的? import time def timer(timeout=0): def decorator(func): def wrapper(*args, **kwargs): # ...

  6. 使用jar命令打war包

    1.打开cmd进入web项目发布文件夹 2.,输入jar -cvf qxpt.war * (*表示当前目录下所有子目录) 3,回车等待执行完成就可以了 4.如果web项目发布文件夹有多个文件夹,而打w ...

  7. django xadmin 模板的定制

    编辑新增等页面对应的modelform为ModelFormAdminView (xadmin.views.edit.ModelFormAdminView) 通过源码分析,新增对象的template属性 ...

  8. ndk学习17: jni之Java调用C&C++

    一.Hello World 1. 定义函数原型 native关键字定义的函数即为jni函数 2.生成头文件 切换到src目录执行: (这个过程可以写脚本自动完成,比如自动拷贝到jni目录) javah ...

  9. 【GoLang】并发小结

    006.并发 1 概念 1.1 goroutine是Go并行设计的核心,goroutine的本质是轻量级线程 1.2 golang的runtime实现了对轻量级线程即goroutine的智能调度管理 ...

  10. ASP.NET 页生命周期概述

    ASP.NET 页生命周期概述 Visual Studio 2005    ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维 ...