【问题标题】:Generate lexicographic permutations生成字典排列
【发布时间】:2020-07-25 17:22:21
【问题描述】:

排列是对象的有序排列。例如,3124 是数字 1、2、3 和 4 的一种可能排列。如果所有排列都按数字或字母顺序列出,我们称之为字典顺序。 0、1、2的字典排列分别是:

012 021 102 120 201 210

如何列出数字 0、1、2、3、4、5、6、7、8 和 9 的字典排列?

【问题讨论】:

标签: bash shell permutation


【解决方案1】:

这是一个普通 bash 中的(低效)实现。它也适用于重复的字符。它确实需要sort实用程序,前提是初始字符串的组成字符已经排序。

$ cat permute

#!/bin/bash

nextperm () {
    local i j rhs

    for ((i = ${#perm} - 1; i > 0; --i)); do
        rhs+=${perm:i:1}
        [[ ${perm:i-1:1} < ${perm:i:1} ]] && break
    done
    ((i <= 0)) && return 1

    for ((j = 0; ; ++j)); do [[ ${rhs:j:1} > ${perm:i-1:1} ]] && break; done

    perm=${perm:0:i-1}${rhs:j:1}${rhs:0:j}${perm:i-1:1}${rhs:j+1}
    echo "$perm"
}

perm=$1
echo "$perm"
while nextperm; do :; done

$ ./permute 123

123
132
213
231
312
321

$ ./permute 1122

1122
1212
1221
2112
2121
2211

【讨论】:

    【解决方案2】:
    $ cat prog.awk
    BEGIN {
      nElem = split(set, mySet)
      if (nElem > 0)
        perms(mySet, nElem)
    }
    
    function perms(set, nElem, perm, cnt, ind, elem) {
      if (nElem == 0) {
        print perm
        return
      }
    
      cnt = 0
      for (ind = 1; cnt < nElem; ind++) {
        if (!(ind in set))
          continue
    
        elem = set[ind]
        delete set[ind]
        perms(set, nElem - 1, perm elem)
        set[ind] = elem
        cnt++
      }
    }
    
    $ awk -v set='1 2 3 4' -f prog.awk
    1234
    1243
    1324
    1342
    1423
    ...
    

    给定一个集合,其元素按字典顺序排序,这将生成字典排列;否则,您需要将其输出通过管道传输到 sort

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多