• 原创:全排列非递归算法:微软给出的算法


    关于全排列的算法研究,有很多,不论述了。采用非递归的算法,是首选。直接上传微软给出的算法:

    /*
      * 字符串全排列最优算法(非递归置换)
      */
     public void permutation(char str[],int m,boolean duplicate){
      int n = str.length;
      if(n < 1 || m < 0 || m > n)
             return;

         if(m == 0) //默认全排列

             m = n;

         int repeat_cnt[] = new int[n]; //循环计数器,一层一个,共 n 个,都初始化为 0
         char tmp_seq[] = new char[n];  //存放排列结果序列的空间
         int layer = 0;                  //当前正在循环层

         int pos;                        //本循环层的层计数器

         while(true)
         {
             if(layer == 0 && repeat_cnt[0] >= n) //当前在第0层,且第0层计数器达到末尾时退出循环
                 break;
             if(layer < m - 1)           //小于n-1层
             {
                 pos = repeat_cnt[layer];
                 if(pos < n)
                 {

                     //层计数器 < n,保存层计数器指向的元素,计数器前进一位,增加一层
                     if(!duplicate)
                     {

                         //不允许重复
                         boolean found = false;
                         for(int i = 0; i < n; ++i)
                         {
                             if(pos + 1 == repeat_cnt[i])
                             {
                                 found = true;
                                 break;
                             }
                         }
                         if(found)
                         {

                             //检查到重复,计数器前进一位,继续
                             repeat_cnt[layer] = repeat_cnt[layer] + 1;
                             continue;
                         }
                     }
                     tmp_seq[layer] = str[pos];
                     repeat_cnt[layer] = repeat_cnt[layer] + 1;
                     layer++;
                 }                //否则,层计数器归零,向上一层

                 else
                 {

                     //否则,层计数器归零,向上一层
                     repeat_cnt[layer] = 0;
                     layer--;
                 }
             }
             else
             {//处理最后一层

                 //第 m - 1 层:计数器每移动一个位置,都是一种组合
                 pos = repeat_cnt[layer];
                 if(pos < n)
                 {
                     if(!duplicate)
                     {

                         //不允许重复
                         boolean found = false;
                         for(int i = 0; i < n; ++i)
                         {
                             if(pos + 1 == repeat_cnt[i])
                             {
                                 found = true;
                                 break;
                             }
                         }
                         if(found)
                         {

                             //检查到重复,计数器前进一位,继续
                             repeat_cnt[layer] = repeat_cnt[layer] + 1;
                             continue;
                         }
                     }

                     tmp_seq[layer] = str[pos];

                     //找到一种组合,将其打印出来

                     for(int i = 0; i < n; ++i)
                         System.out.print(tmp_seq[i]);
                      System.out.println();

                     //层计数器前进 1 位

                     repeat_cnt[layer] = repeat_cnt[layer] + 1;
                 }
                 else
                 {

                     //n-1 层计数器到达末尾,将层计数器归零 ,返回上层
                     repeat_cnt[layer] = 0;
                     layer--;
                 }
             }
         }
     }

  • 相关阅读:
    SQL SERVER代码生成器必备
    jquery实现ajax提交表单信息
    linux下的守护进程
    异步在单进程系统中的重要性
    php常用函数(持续更新)
    根据html容器大小和显示文字多少调节字体大小
    弹出框插件
    本地连接虚拟机上面的redis
    Flume学习——BasicTransactionSemantics
    Flume学习——BasicChannelSemantics
  • 原文地址:https://www.cnblogs.com/txq157/p/6094343.html
Copyright © 2020-2023  润新知