shell script para encontrar a combinação dos elementos da matriz

1

Eu tenho um script de shell no qual eu defini uma matriz. O array contém mais de 2 elementos. Eu preciso encontrar a combinação de todos os elementos da minha matriz. Suponha que, se minha matriz tiver os elementos, {12345, 56789, 98765} , estou tentando obter a saída como

12345, 56789
12345, 98765
56789, 98765

Eu tentei o código php de aqui .

<?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'));
?>

Eu recebo a saída como

12345 56789 98765
56789 12345 98765
12345 98765 56789
98765 12345 56789
56789 98765 12345
98765 56789 12345

É possível obter a combinação em saída de 2 elementos? Não estou preocupado com o pedido e, portanto, se A B for obtido como uma combinação, não preciso do reverso ( B A ).

    
por Ramesh 08.04.2014 / 22:13

2 respostas

1

Tudo que você precisa é printf. É o print function - esse é o seu trabalho.

printf '%s\t%s\n' ${array[@]}

Você faz assim:

( set -- 12345 56789 98765; for i ; do 
    eval set -- $(printf '"$%s" ' 'seq 2 $#' 1)
    echo "$*"
done )

OUTPUT

56789 98765 12345
98765 12345 56789
12345 56789 98765

Eu não precisei de eval - isso foi burro. Aqui está um melhor:

( set -- 12345 56789 98765 ; 
until [ $((i=i+1)) -gt $# ] ; do
    set -- $(s=$1 ; shift ; printf '%s\n' "$@" "$s")
    printf '%s ' "$@" ; echo
done)

OUTPUT

56789 98765 12345
98765 12345 56789
12345 56789 98765

E se você quiser apenas dois elementos, basta mudá-lo um pouco mais uma linha:

( 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
    )

OUTPUT

56789   98765
12345   98765
12345   56789

Eu faço isso o tempo todo, mas nunca os bashisms. Eu sempre trabalho com o array de shell real, então demorou alguns minutos para conseguir isso.

Aqui está um pequeno roteiro que escrevi para outra resposta:

    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

Isso grava em 26 arquivos. Eles se parecem com isso apenas eles incrementam por arquivo:

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
    
por 09.04.2014 / 03:29
1

Eu descobri a maneira de imprimir os elementos em combinações de tamanho de 2 elementos. O código php é como abaixo.

<?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";
    }
}
?>

O código acima imprime a saída como

56789   12345
98765   12345
98765   56789

A referência para o código acima é aqui .

    
por 08.04.2014 / 22:35