![shell脚本查找数组元素的组合](https://linux22.com/image/52798/shell%E8%84%9A%E6%9C%AC%E6%9F%A5%E6%89%BE%E6%95%B0%E7%BB%84%E5%85%83%E7%B4%A0%E7%9A%84%E7%BB%84%E5%90%88.png)
我有一个 shell 脚本,其中定义了一个数组。该数组包含 2 个以上元素。我需要找到数组中所有元素的组合。假设,如果我的数组有元素,{12345, 56789, 98765}
,我试图得到输出,
12345, 56789
12345, 98765
56789, 98765
我尝试了 php 代码这里。
<?php
function pc_permute($items, $perms = array( )) {
if (empty($items)) {
print join(' ', $perms) . "\n";
} else {
for ($i = count($items) - 1; $i >= 0; --$i) {
$newitems = $items;
$newperms = $perms;
list($foo) = array_splice($newitems, $i, 1);
array_unshift($newperms, $foo);
pc_permute($newitems, $newperms);
}
}
}
pc_permute(split(' ', '12345 56789 98765'));
?>
我得到的输出为
12345 56789 98765
56789 12345 98765
12345 98765 56789
98765 12345 56789
56789 98765 12345
98765 56789 12345
是否有可能获得 2 个元素大小的输出组合?我不关心顺序,所以如果A B
是作为组合获得的,我不需要相反的(B A
)。
答案1
你所需要的就是printf.
它print function
——这就是它的工作。
printf '%s\t%s\n' ${array[@]}
你这样做:
( set -- 12345 56789 98765; for i ; do
eval set -- $(printf '"$%s" ' `seq 2 $#` 1)
echo "$*"
done )
输出
56789 98765 12345
98765 12345 56789
12345 56789 98765
我不需要eval
——那太愚蠢了。这是一个更好的:
( set -- 12345 56789 98765 ;
until [ $((i=i+1)) -gt $# ] ; do
set -- $(s=$1 ; shift ; printf '%s\n' "$@" "$s")
printf '%s ' "$@" ; echo
done)
输出
56789 98765 12345
98765 12345 56789
12345 56789 98765
然后,如果您只想要两个元素,只需稍微更改一下即可 - 再一行:
( set -- 12345 56789 98765 ;
until [ $((i=i+1)) -ge $# ] ; do
set -- $(s=$1 ; shift ; printf '%s\n' "$@" "$s")
v="${v}$(printf '%s ' "$@")"
done ; printf "%s\t%s\n" $v
)
输出
56789 98765
12345 98765
12345 56789
我一直这样做,但从不羞辱。我总是使用真正的贝壳阵列,所以花了几分钟才掌握它。
这是我为另一个答案编写的一个小脚本:
abc="a b c d e f g h i j k l m n o p q r s t u v w x y z"
for l in $abc ; do {
h= c= ; [ $((i=i+1)) -gt 26 ] && n=$((n+26)) i=
xyz=$(x=${xyz:-$abc} ;\
printf %s\\n ${x#?} $l)
mid=$(set -- $xyz ; eval echo \$$((${#}/4))) ;\
echo "$mid $l" >&2 ;
[ $(((i+n)%${mod=3})) -eq 0 ] && c="$mid" h="${xyz%"$mid"*}"
line="$(printf '%s ' $h $c ${xyz#"$h"})"
printf "%s$(printf %s ${xyz#?}${mid})\n" \
${line} >|/tmp/file$((i+n))
} ; done
这将写入 26 个文件。它们看起来像这样,只是每个文件递增:
bcdefghijklmnopqrstuvwxyzag
ccdefghijklmnopqrstuvwxyzag
dcdefghijklmnopqrstuvwxyzag
ecdefghijklmnopqrstuvwxyzag
fcdefghijklmnopqrstuvwxyzag
gcdefghijklmnopqrstuvwxyzag
hcdefghijklmnopqrstuvwxyzag
icdefghijklmnopqrstuvwxyzag
jcdefghijklmnopqrstuvwxyzag
kcdefghijklmnopqrstuvwxyzag
lcdefghijklmnopqrstuvwxyzag
mcdefghijklmnopqrstuvwxyzag
ncdefghijklmnopqrstuvwxyzag
ocdefghijklmnopqrstuvwxyzag
pcdefghijklmnopqrstuvwxyzag
qcdefghijklmnopqrstuvwxyzag
rcdefghijklmnopqrstuvwxyzag
scdefghijklmnopqrstuvwxyzag
tcdefghijklmnopqrstuvwxyzag
ucdefghijklmnopqrstuvwxyzag
vcdefghijklmnopqrstuvwxyzag
wcdefghijklmnopqrstuvwxyzag
xcdefghijklmnopqrstuvwxyzag
ycdefghijklmnopqrstuvwxyzag
zcdefghijklmnopqrstuvwxyzag
acdefghijklmnopqrstuvwxyzag
答案2
我找到了以 2 个元素大小的组合打印元素的方法。 php代码如下。
<?php
function pc_array_power_set($array) {
// initialize by adding the empty set
$results = array(array( ));
foreach ($array as $element)
foreach ($results as $combination)
array_push($results, array_merge(array($element), $combination));
return $results;
}
$set = array('12345', '56789', '98765');
$power_set = pc_array_power_set($set);
foreach (pc_array_power_set($set) as $combination) {
if (2 == count($combination)) {
print join("\t", $combination) . "\n";
}
}
?>
上面的代码将输出打印为:
56789 12345
98765 12345
98765 56789
上述代码的参考是这里。