【问题标题】:Permutation algorithm for n characters in x positionsx位置中n个字符的置换算法
【发布时间】:2019-03-06 21:22:59
【问题描述】:

例如{&, *, %} 的置换算法被放置在 8 个位置:

  1. &&&&&&&&&
  2. &&&&&&&&*
  3. &&&&&&&&%
  4. &&&&&&&*%
  5. &&&&&&&**

...

我在网上看到的堆的排列算法只适用于字符数等于位置数的那些,以及那些可以处理不等字符数和位置数的那些,只适用于整数,而不适用于字符.我还不得不说到目前为止我还没有达到任何工作算法,因为我对算法一无所知。我试过一次,看到堆的算法后,我无法命名它的算法!如果有帮助:

  1. & 添加到输出数组。
  2. % 添加到新索引的输出数组中。
  3. * 添加到新索引的输出数组中。
  4. 对每三个执行递归算法。

但我显然无法处理数组索引。 我也尝试使用从 0 到 2 的数字来表示 &、%、*;但我没有得到一个好的答案。

【问题讨论】:

  • 提示:使用数字 0、1 和 2 来表示 &*%
  • @SaniSinghHuttunen 我试过了,没用。至少我找不到使用它的方法。
  • 8 个位置,每个位置有 3 个可能的字符,总共 3^8 个输出。所以从一个运行 6561 次的循环开始。从那里去哪里的详细信息取决于您使用的编程语言。

标签: arrays algorithm permutation heaps-algorithm


【解决方案1】:

您可以使用标准的“里程表”方法 (IDEOne):

static void permute(String str, int len)
{    
  char[] chars = str.toCharArray();

  int[] idx = new int[len];

  char[] perm = new char[len];    
  Arrays.fill(perm, chars[0]);

  while(true)
  {      
    System.out.println(new String(perm));

    int k=idx.length-1;
    for(; k>=0; k--)
    {
      idx[k] += 1;
      if(idx[k] < chars.length) 
      {
        perm[k] = chars[idx[k]];
        break;
      }
      idx[k] = 0;
      perm[k] = chars[idx[k]];
    }
    if(k < 0) break;
  }
}

测试:

public static void main(String[] args)
{
  permute("&*%", 8);
}

输出:

&&&&&&&&
&&&&&&&*
&&&&&&&%
&&&&&&*&
&&&&&&**
&&&&&&*%
&&&&&&%&
&&&&&&%*
&&&&&&%%
&&&&&*&&
<snip>
%%%%%%**
%%%%%%*%
%%%%%%%&
%%%%%%%*
%%%%%%%%

【讨论】:

    【解决方案2】:

    可以通过以3为底数列出排列。

    • & = 0
    • * = 1
    • % = 2

    算法(伪代码)

    Start i=00000000 and end at 22222222 in base 3:
        str_i = encode i in { &, *, % } character set
        print str_i
        i = i + 1 (in base 3)
    

    代码示例(在 Python 中)

    def main():
      start = int('00000000', 3)
      end = int('22222222', 3)
      for i in range(start, end + 1):
        # convert binary to base 3
        perm_base3 = str_base(i, 3)
        perm_charset = encode_to_charset(perm_base3)
        print(perm_charset)
    
    # custom character set
    # & = 0
    # * = 1
    # % = 2
    def encode_to_charset(str_number_base3):
      ret = []
      for c in str_number_base3:
        if c == '0':
          ret.append('&')
        elif c == '1':
          ret.append('*')
        elif c == '2':
          ret.append('%')
        else:
          pass #TODO handle error here
      return "".join(ret)
    
    #
    # Utility functions
    # https://stackoverflow.com/questions/2063425/python-elegant-inverse-function-of-intstring-base
    #
    def digit_to_char(digit):
        if digit < 10: return chr(ord('0') + digit)
        else: return chr(ord('a') + digit - 10)
    
    def str_base(number,base):
        if number < 0:
            return '-' + str_base(-number,base)
        else:
            (d,m) = divmod(number,base)
            if d:
                return str_base(d,base) + digit_to_char(m)
            else:
                return digit_to_char(m)
    
    main()
    

    实时示例(在 repl.it 上)

    https://repl.it/@KyleMarshall1/PermutationAlgorithm

    【讨论】:

    • 非常感谢您为我花费的时间,但这不起作用,您测试了吗?
    • 是的,我刚刚又运行了一次。您是否尝试过 repl.it 上的实时示例?
    • 我现在又跑了一次,好吧,我不希望它显示少于8个位置的人;但它运行正常。
    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2016-08-04
    • 2020-02-09
    相关资源
    最近更新 更多