section 1. 字符串的全排列。譬如假定给定字符串为“abc”,则全排列是“abc”的所有可能组合,且每一个字符都不相关。如“aaa”的全排列仍然有6种(3!=6)。
  可以按照字母顺序来排列这些字符。如果输入"ab cd",这意味着第一个字符将是“a”打头,其次是“b”...这样的排列就具有如下变化规律:最右边字符的变化将快于左边字符的变化。换句话说,为当前位置选择一个字符,向右移动一个位置进行全排列——递归出现了。 找出位置n的字符的全排列,需要把允许出现在位置n上的字符依次放到位置上,然后为位置n的每一个新字符找出位置n+1的全排列。当n大于字符串的个数时就找到了全排列。此时需要先把当前字符输出,然后回到n-1位置去更改字母(基底情况)。
  把 程序分为基底情况和递归情况是良好的程序设计方法。一种大幅提高递归效率的优化方法是:如果下次递归进入基地情况,则不再递归而是直接进入基底。以全排列为例,将减少n!次函数调用。这种直接进入基底的优化方法称为“断臂递归(arms length recurision)”.下面是全排列的AS3代码:
class Permute
{
  public static function permute(test:String):void
  {
    var out:Array = new Array(test.length);
    var used:Array = new Array(test.length);
    for(var i:uint = 0; i < used.length; i++)
      used[i] = false;
    doPermute(test,out,used,0);
  }
  
  private static function doPermute(inString:String, out:Array, used:Array, recursLen:uint):void
  {
    var i:uint;
    if(used.length == recursLen)
    {
      trace(out);
      return;
    }
    for(i = 0; i < used.length; i++)
    {
      if(used[i])
        continue;
      out[recursLen] = inString.charAt(i);
      used[i] = true;
      doPermute(inString,out,used,recursLen + 1);
      used[i] = false;
    }
  }
}

section 2. 字符串的全组合。组合与排列不同的一点是,如果输入“abc”,则“ab”与“ba”是一种组合,而“ab”与“bc”才是不同的组合。组合的算法使用递归实现仍然极其方便:
   对从输入起点字符到输入字符串的最后一个字符之间的各个字符,循环:
     为输出字符串(数组)的当前字符选择一个字符
     把这些字符输出到输出字符串(数组)里
     如果当前字符不是输入字符串的最后一个字符
       从下一个位置开始生成全排列,循环将从当前字符后面的字符开始

代码如下:


class Combine
{
  public static function combine(test:String):void
  {
    var out:Array = new Array(test.length);
    doCombine(test,out,0,0);
  }
  
  private static function doCombine(inString:String, out:Array, recusLen:uint, start:uint):void
  {
    for(var i:uint = start; i < out.length; i++)
    {
      out[recusLen] = inString.charAt(i);
      if(recusLen < out.length-1)
        out[recusLen + 1] = "";
      trace(out);
      if(i < out.length - 1)
        doCombine(inString,out,recusLen + 1,i + 1);
    }        
  }
}

section 3. 压轴大戏:电话键单词组合。手机的拨号盘上每一个数字对应三个字母。如何对给点的一个电话号码输出全部单词的排列?
  写出几种排列后将发现,这些排列中某位置的字母将影响右边的字母。即当位置i处的字母发生变化时,i+1处的单词将轮遍取到所有可能的值。i与I+1构成了递归关系。so:
如果当前数字超出了最后一位数字
    输出当前单词
  否则
    对当前位置所对应的三个字母,按照从低到高的顺序喜欢
       用字母代替当期数字
       前进到下一个数字并且递归
       如果当前数字是0或者1则返回(0,1没有对应字母)

  算法代码:


class PrintPhoneNumber
{
  private static const PHONE_NUMBER_LENGTH:uint = 7;
    
  public static function iterPrintPhoneNum(phoneNum:uint):void
  {
    var result:Array = new Array(PHONE_NUMBER_LENGTH);
    doPrintPhoneNum(phoneNum, 0, result);
  }
  
    
  private static function doPrintPhoneNum(phoneNum:uint, curDigit:uint, result:Array):void
  {
    var i:uint;
    
    if(curDigit == PrintPhoneNumber.PHONE_NUMBER_LENGTH)
    {
      trace(result);
      return;
    }
    
    for(i = 1; i <= 3; i++)
    {
      var p:uint = uint(phoneNum.toString().charAt(curDigit));
      result[curDigit] = getCharKey(p,i);
      doPrintPhoneNum(phoneNum, curDigit + 1, result);
      p = uint(phoneNum.toString().charAt(curDigit));
      if( p== 0 || p == 1)
        return;
    }
  }
  
  private static function getCharKey(phoneKey:uint, place:uint):String
  {
    var key:Array =[
            [null,null,null],
            [null,null,null],
            ["a","b","c"],
            ["d","e","f"],
            ["g","h","i"],
            ["j","k","l"],
            ["m","n","o"],
            ["p","r","s"],
            ["t","u","v"],
            ["w","x","y"]
             ];
    return key[phoneKey][place-1];
  }
}

该题另外有一种循环解法:
    一个字母一个字母的创建出第一个单词
    无限循环
      输出当前单词
      递增最后一个字母并且对它前面的字母做相应改变
      如果第一个字母已经改变,解除循环


public static function CricPrintPhoneNum(phoneNum:uint):void
{
  var i:int;
  var result:Array = new Array(PHONE_NUMBER_LENGTH);
  for(i = 0; i< result.length; i++)
    result[i] = getCharKey(uint(phoneNum.toString().charAt(i)),1);
  
  while(true)
  {
    trace(result);
    for(i = PHONE_NUMBER_LENGTH - 1; i >= -1; i--)
    {
      var a:uint;
      if(i == -1)
        return
      if(getCharKey(uint(phoneNum.toString().charAt(i)),3) == result[i] || 
         uint(phoneNum.toString().charAt(i)) == 0 || 
         uint(phoneNum.toString().charAt(i)) == 1)
      {
        result[i] = getCharKey(uint(phoneNum.toString().charAt(i)),1);
      }          
      else if(getCharKey(uint(phoneNum.toString().charAt(i)),1) == result[i])
      {
        result[i] = getCharKey(uint(phoneNum.toString().charAt(i)),2);
        break;
      }          
      else if(getCharKey(uint(phoneNum.toString().charAt(i)),2) == result[i])
      {
        result[i] = getCharKey(uint(phoneNum.toString().charAt(i)),3);
        break;
      }
    }
  }
  
}

排列与组合中的递归策略(as3.0)相关推荐

  1. 排列与组合的Java递归实现 (参考)

    我们在笔试面试过程中经常会遇到关于排列与组合的问题,其实这些可以通过递归简单的实现,看下面两个例子: (1)关于字符串排列的问题 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc, ...

  2. 排列和组合简单的递归思路以及C++实现

    本文将讲解如何通过递归的方法实现全排列和组合,会详细讲解递归的思路,最后还会给出c++实现的源码.先前学习数据结构和算法的时候一直没有弄明白它们的递归思路,今日遇到,细一思考,发现并没有之前那么难,于 ...

  3. 排列、组合问题(递归)

    这里主要介绍字符串排列组合问题,高中数学常见的题目,不用详细介绍,看例子就可以解决问题 "1212" 全排列结果为 1212,1221,1122,2112,2121,2211 组合 ...

  4. 搜索技术——排列和组合问题

    搜索使用的算法是BFS和DFS,BFS用队列,DFS用递归具体实现.在BFS和DFS的基础上可以扩展出A*算法.双向广搜算法.迭代加深算法.IDA*等技术. 暴力法:把所有可能的情况都罗列出来,然后逐 ...

  5. 组合 公式 计算机,排列与组合的概念与计算公式

    排列与组合的概念与公式 1.排列及计算公式 从n个不同元素中,任取m(m≤n)个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列:从n个不同元素中取出m(m≤n)个元素的所有排列 ...

  6. 通用的非递归排列和组合算法[附源码]

    动机 Apache Math包中有很多关分布的算法,但是没有找到排列组合相关的算法.索性自己写一个.排列组合可以分两个算法: 组合算法,就是在一个数组中取出m(小于等于数组的长度 n)个对象,有多少中 ...

  7. 什么时候用到全排列_请问在排列组合中,在什么情况下要乘以全排列

    展开全部 在比考虑每个事件出现的次序时,这种次序不同影响了结果,则需用全排列,在排列组合636f707962616964757a686964616f31333433633961中,均分问题要除以全排列 ...

  8. 约数个数 (排列组合中的乘法原理)

    问题 A: 约数个数 时间限制: 2 Sec  内存限制: 128 MB 提交: 313  解决: 39 提交 状态 讨论版 命题人:admin 题目描述 p^q表示p的q次方,正整数M可以分解为M= ...

  9. python中如何求列表中的和_python实现求解列表中元素的排列和组合

    求解列表中元素的排列和组合问题这个问题之前就遇到过几次没有太留意,最近在做题的时候遇上挺多的排列组合问题的,想来有必要温习一下了,今天花点时间写一下,之前都是手工写的,后来知道可以直接使用python ...

最新文章

  1. Zookeeper 在Hadoop中的应用
  2. 红橙Darren视频笔记 界面优化与屏幕适配(下)
  3. python构建知识库_使用Mediawiki构建个人知识库
  4. (八)java版spring cloud+spring boot+redis多租户社交电子商务平台 -SSO单点登录之OAuth2.0登录认证(2)...
  5. 在linux 创建网络会话和绑定两块网卡
  6. 型管件的作用_W型柔性铸铁排水管适用范围
  7. HBase原理-数据读取流程解析
  8. 配置多个git账号_git配置账号(用户名/邮箱)
  9. 分布形态的度量-偏度系数与峰度系数的探讨
  10. Python -- 使用if语句处理列表
  11. 网站分析平台:是选择百度统计,还是 Google Analytics 呢?
  12. html间超链接怎么做,超链接怎么做
  13. 齐纳二极管 稳压二极管 SOD123封装 正负区分
  14. pe没法给服务器装系统吗,U盘重装系统无法进入PE解决方法
  15. 鸿蒙系统为国,华为发布鸿蒙系统,国人为之骄傲
  16. Redis(3.2.3)集群部署实战
  17. 论文阅读2018:Internet Protocol Cameras with No Password Protection: An Empirical Investigation
  18. Android多人视频聊天应用的开发(二)一对一聊天
  19. sourcetree拉取LFS
  20. 成都百知教育简述Shopee新卖家该如何做好店铺运营规划?

热门文章

  1. EFR32 gecko 2生产烧录
  2. 十大算法--支持向量机
  3. Nintendo Switch在线订阅包含什么?
  4. KendoUI模板引擎 - 结合组件使用
  5. 硬盘被重新分区并格式化后数据恢复教程 (图文并茂)
  6. termux 安装 kali
  7. 阿里P8大牛手把手教你!15个经典面试问题及回答思路,全套教学资料
  8. 《用C#制作PDF文件全攻略》
  9. Leetcode分类练习-查找(2)对撞指针
  10. 程序员专业常用英语词汇