Remove o array de entradas de outro array

1

Eu tenho 2 matrizes

    a=(1,2,3,4,5)
    b=(2,4)

a saída deve ser

    c=(1,3,5) 

(que deve ser o resultado de a-b)

Eu tentei usar

    unset a[${b}] 

alguma ideia?

o que tenho trabalhado agora é um loop que percorre 700.000 iterações

    
por dtb 13.05.2015 / 15:30

4 respostas

4

Primeiro de tudo, se você quiser fazer isso para 700.000 iterações, você realmente deve procurar algo diferente de bash. Além disso, o que você mostra não é um array no bash, é uma string 1 . Arrays são separados por espaços, não por vírgulas.

Dito isto, aqui está uma maneira bash, assumindo verdadeiras matrizes:

a=(1 2 3 4 5)
b=(2 4)
c=( $(printf "%s\n" "${a[@]}" "${b[@]}" | sort | uniq -u) )

Se você realmente tiver strings separadas por vírgula e não arrays, use isso:

a=(1,2,3,4,5)
b=(2,4)
c=( $(sed 's/,/\n/g' <(printf "%s\n" "${a[@]}" "${b[@]}") | sort | uniq -u) )

Como alternativa, você pode usar o perl:

#!/usr/bin/perl
my @A=(1,2,3,4,5);
my @B=(2,4);
my %k;
map{$k{$_}++} (@A,@B);
my @C=grep($k{$_}==1,keys(%k));
print "@C\n";

1 Estritamente falando, é uma matriz com um elemento, mas que é essencialmente o mesmo que uma string no que diz respeito ao bash.

    
por terdon 13.05.2015 / 17:37
1

A complexidade da tarefa (O (N ^ 2)) não pode ser reduzida; assumindo apenas o que foi explicitamente fornecido (ou seja, nenhuma hipótese para os valores de ambos os conjuntos a e b ) o código abaixo apenas verificará se cada valor presente em a também está presente em b , e se o valor Se o valor estiver presente, ele quebrará o loop for interno (a única otimização possível com a hipótese fornecida) e adicionará o valor a c ; com mais pistas sobre o conteúdo das matrizes a e b (ou seja, se os valores em cada matriz puderem ser repetidos e se as matrizes forem classificadas), pode haver mais espaço para melhorias:

#!/bin/bash

a=(1 2 3 4 5)
b=(2 4)
for i in ${a[@]}
do
match=0
    for j in ${b[@]}
    do
        if [ "${i}" == "${j}" ]
        then
            match=1
            break
        fi
    done
if [ "${match}" == 0 ]
then
    c+=($i)
fi
done
echo ${c[@]}
    
por kos 13.05.2015 / 16:22
1

O caminho perl . Este script exibe todos os elementos na matriz a , que também estão contidos na matriz b .

#!/usr/bin/perl
my @a = (1,2,3,4,5);
my @b = (2,4,7,8,9,10);

# Create a hashmap with the entries in b as keys,
# but without values for the keys for a better lookup
# (exists ($hash{$element}))
my %hash;
@hash{@b}=();

foreach my $element (@a) {print "$element " unless exists($hash{$element})}
print "\n";

Saída:

1 3 5
    
por A.B. 13.05.2015 / 15:57
1

Em python , entradas como:

a=(1,2,3,4,5)
b=(2,4)

são iteráveis e conhecidos como tuples .

Sua tarefa pode ser facilmente executada em python :

#!/usr/bin/env python2
a = (1, 2, 3, 4, 5)
b = (2, 4)
c = tuple(i for i in a if i not in b)
print c

Saída:

(1, 3, 5)

Aqui encontramos os valores da tupla a , que não existem na tupla b e os colocamos em outra tupla c . Observe também que essa operação será rápida e eficiente para a memória para conjuntos de dados maiores, já que usamos python expressão do gerador .

    
por heemayl 13.05.2015 / 20:18