考虑以下字符串
abcd
我可以返回2个字符的排列 (cartesian product) 像这样
$ echo {a,b,c,d}{a,b,c,d}
aa ab ac ad ba bb bc bd ca cb cc cd da db dc dd
但是我想删除多余的条目,例如
ba ca cb da db dc
和无效条目
aa bb cc dd
所以我留下了
ab ac ad bc bd cd
答案 0 :(得分:6)
这是一个纯粹的打击:
#!/bin/bash
pool=( {a..d} )
for((i=0;i<${#pool[@]}-1;++i)); do
for((j=i+1;j<${#pool[@]};++j)); do
printf '%s\n' "${pool[i]}${pool[j]}"
done
done
另一个:
#!/bin/bash
pool=( {a..d} )
while ((${#pool[@]}>1)); do
h=${pool[0]}
pool=("${pool[@]:1}")
printf '%s\n' "${pool[@]/#/$h}"
done
它们可以写成函数(或脚本):
get_perms_ordered() {
local i j
for((i=1;i<"$#";++i)); do
for((j=i+1;j<="$#";++j)); do
printf '%s\n' "${!i}${!j}"
done
done
}
或
get_perms_ordered() {
local h
while (("$#">1)); do
h=$1; shift
printf '%s\n' "${@/#/$h}"
done
}
用作:
$ get_perms_ordered {a..d}
ab
ac
ad
bc
bd
cd
最后一个可以很容易地转换为递归函数,以获得给定长度的有序排列(无需替换 - 我使用愚蠢的球 - 瓮概率词汇表),例如,
get_withdraws_without_replacement() {
# $1=number of balls to withdraw
# $2,... are the ball "colors"
# return is in array gwwr_ret
local n=$1 h r=()
shift
((n>0)) || return
((n==1)) && { gwwr_ret=( "$@" ); return; }
while (("$#">=n)); do
h=$1; shift
get_withdraws_without_replacement "$((n-1))" "$@"
r+=( "${gwwr_ret[@]/#/$h}" )
done
gwwr_ret=( "${r[@]}" )
}
然后:
$ get_withdraws_without_replacement 3 {a..d}
$ echo "${gwwr_ret[@]}"
abc abd acd bcd
答案 1 :(得分:4)
您可以使用awk过滤掉您不想要的条目:
echo {a,b,c,d}{a,b,c,d} | awk -v FS="" -v RS=" " '$1 == $2 { next } ; $1 > $2 { SEEN[ $2$1 ] = 1 ; next } ; { SEEN[ $1$2 ] =1 } ; END { for ( I in SEEN ) { print I } }'
详情:
echo {a,b,c,d}{a,b,c,d} \
| awk -v FS="" -v RS=" " '
# Ignore identical values
$1 == $2 { next }
# Reorder and record inverted entries
$1 > $2 { SEEN[ $2$1 ] = 1 ; next }
# Record everything else
{ SEEN[ $1$2 ] = 1 }
# Print the final list
END { for ( I in SEEN ) { print I } }
'
FS=""
告诉awk每个字符都是一个单独的字段。
RS=" "
使用空格分隔记录。
答案 2 :(得分:1)
确定有人会在一行awk中执行此操作,但这是bash中的内容:
#!/bin/bash
seen=":"
result=""
for i in "$@"
do
for j in "$@"
do
if [ "$i" != "$j" ]
then
if [[ $seen != *":$j$i:"* ]]
then
result="$result $i$j"
seen="$seen$i$j:"
fi
fi
done
done
echo $result
输出:
$ ./prod.sh a b c d
ab ac ad bc bd cd
$ ./prod.sh I have no life
Ihave Ino Ilife haveno havelife nolife
答案 3 :(得分:0)
这是一个伪代码,根据你的限制来实现这一点,和 为你的角色使用数组:
for (i=0;i<array.length;i++)
{
for (j=i+1;j<array.length;j++)
{
print array[i] + array[j]; //concatenation
}
}
答案 4 :(得分:0)