如何用 N! 在 bash 中进行排列输入?
How to make permutation in bash with N! input?
我必须使用 "eval" 和 "seq" 命令在 bash 中进行排列。所以我必须先做一个可能包含相同数字的排列,然后我必须以某种方式过滤它。
老师告诉我必须用两个cycle/period,一个在另一个里。但是我不知道怎么做。
输入如下:
3
输出应该是:
123
132
213
231
312
321
如果有人能帮助我,那就太好了!
编辑:
我想知道如何使用这些命令来完成,我的朋友是这样告诉我的:http://pastebin.com/wM2U1SuT
老师告诉我它太好了,我们还没有达到这个水平..我应该用 seq 和 eval 来做,即使它不是那么好。第二个问题是输入的是123,不是3,好像是3!..
这是一个排列问题,所以我发现其他人已经做到了。可以看到答案Generating permutations using bash
所以通过答案,你可以这样写代码:
perm() {
local items=""
local out=""
local i
[[ "$items" == "" ]] && echo "$out" && return
for (( i=0; i<${#items}; i++ )) ; do
perm "${items:0:i}${items:i+1}" "$out${items:i:1}"
done
}
test() {
local number=""
local iniitem="$(seq -s' ' 1 ${number} | sed -n 's/ //g;p')"
perm "$iniitem"
}
然后你可以像这样使用函数:
test 3
:
输出:
123
132
213
231
312
321
我知道这不是 OP 想要的 seq+eval 解决方案,但如果将来有人正在寻找替代方案,这里是 the Wikipedia article on Heap's Algorithm 中描述的 generate()
函数的实现在 awk 中解决这个问题:
$ cat tst.awk
function generate(n,A, i) {
if (n == 1) {
output(A)
}
else {
for (i=0; i<(n-1); i++) {
generate(n-1, A)
swap(A, (n%2?0:i), n-1)
}
generate(n-1, A)
}
}
BEGIN{
if (n>0) {
for (i=1; i<=n; i++) {
A[i-1] = i
}
generate(n, A)
}
}
function output(a, i,g) {g=length(a); for (i=0;i<g;i++) printf "%s%s",a[i],(i<(g-1)?"":ORS)}
function swap(a,x,y, t) {t=a[x]; a[x]=a[y]; a[y]=t }
$ awk -v n=3 -f tst.awk | sort
123
132
213
231
312
321
我尽可能地坚持 the Wikipedia article 命名和其他约定,包括从零开始数组而不是典型的 awk 1,以便于在该文章和 awk 代码之间进行比较。
如果有人好奇,这里是解决方案:
input=3
for i in $(eval echo " {1..$input}{1..$input}{1..$input} "); do
OK=yes
for pos1 in $(seq 0 $((x,1)) ); do
for pos2 in $(seq 0 $((x,1)) ); do
if [ $pos1 != $pos2 ]; then
if [ ${i:$pos1:1} == ${i:$pos2:1} ]; then
OK=no
fi
fi
done
done
if [ $OK = yes ]; then
echo $i
fi
done
我必须使用 "eval" 和 "seq" 命令在 bash 中进行排列。所以我必须先做一个可能包含相同数字的排列,然后我必须以某种方式过滤它。
老师告诉我必须用两个cycle/period,一个在另一个里。但是我不知道怎么做。
输入如下:
3
输出应该是:
123
132
213
231
312
321
如果有人能帮助我,那就太好了!
编辑: 我想知道如何使用这些命令来完成,我的朋友是这样告诉我的:http://pastebin.com/wM2U1SuT 老师告诉我它太好了,我们还没有达到这个水平..我应该用 seq 和 eval 来做,即使它不是那么好。第二个问题是输入的是123,不是3,好像是3!..
这是一个排列问题,所以我发现其他人已经做到了。可以看到答案Generating permutations using bash
所以通过答案,你可以这样写代码:
perm() {
local items=""
local out=""
local i
[[ "$items" == "" ]] && echo "$out" && return
for (( i=0; i<${#items}; i++ )) ; do
perm "${items:0:i}${items:i+1}" "$out${items:i:1}"
done
}
test() {
local number=""
local iniitem="$(seq -s' ' 1 ${number} | sed -n 's/ //g;p')"
perm "$iniitem"
}
然后你可以像这样使用函数:
test 3
:
输出:
123
132
213
231
312
321
我知道这不是 OP 想要的 seq+eval 解决方案,但如果将来有人正在寻找替代方案,这里是 the Wikipedia article on Heap's Algorithm 中描述的 generate()
函数的实现在 awk 中解决这个问题:
$ cat tst.awk
function generate(n,A, i) {
if (n == 1) {
output(A)
}
else {
for (i=0; i<(n-1); i++) {
generate(n-1, A)
swap(A, (n%2?0:i), n-1)
}
generate(n-1, A)
}
}
BEGIN{
if (n>0) {
for (i=1; i<=n; i++) {
A[i-1] = i
}
generate(n, A)
}
}
function output(a, i,g) {g=length(a); for (i=0;i<g;i++) printf "%s%s",a[i],(i<(g-1)?"":ORS)}
function swap(a,x,y, t) {t=a[x]; a[x]=a[y]; a[y]=t }
$ awk -v n=3 -f tst.awk | sort
123
132
213
231
312
321
我尽可能地坚持 the Wikipedia article 命名和其他约定,包括从零开始数组而不是典型的 awk 1,以便于在该文章和 awk 代码之间进行比较。
如果有人好奇,这里是解决方案:
input=3
for i in $(eval echo " {1..$input}{1..$input}{1..$input} "); do
OK=yes
for pos1 in $(seq 0 $((x,1)) ); do
for pos2 in $(seq 0 $((x,1)) ); do
if [ $pos1 != $pos2 ]; then
if [ ${i:$pos1:1} == ${i:$pos2:1} ]; then
OK=no
fi
fi
done
done
if [ $OK = yes ]; then
echo $i
fi
done