Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

diokhan

PERL contar numero de vezes que aparece

Mensagens Recomendadas

diokhan

boas,

como o nome do tópico indica, eu quero contar o numero de vezes que uma determinada string aparece dentro de um array, por exemplo, se tiver o array @array = (1, 2, 3, 1, 2, 4, 6, 7, 1) e quero contar quantas vezes aparecem o numero "1", já tive a ver a função grep, mas penso que não seja esta a melhor função para o que preciso

pensei fazer dentro de um ciclo while mas esta sempre a encontrar o mesmo registo, mesmo só contendo 1 única vez a string no array ele continuava a contar

se alguém puder dar uma ideia ou dica agradecia :)


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Fazes um loop por todo o vector e depois dentro desse loop verificas se o elemento actual é igual ao que pretendes procurar, se for incrementas uma variável de controlo, se não for não fazes nada. Atenção, a variável de controlo tem de ser inicializado com 0.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
falco

A função grep é a melhor solução.

#!/usr/bin/env perl

use strict;
use warnings;

my @array = (1,2,3,4,5,6);
my @matchs = grep {/^1$/}; 
print "Found: ".int(@matchs)."\n";

Se leres a documentação oficial do Perl, também vais saber que podes utilizar colocar parte parte do padrão desta expressão regular como uma variável, fazendo que com que possas definir antes qual o exacto padrão que queres procurar, permitindo mais re-aproveitamento do código.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
diokhan

eu testei o grep, mas ele "apaga" do array o elemento que procuro, é assim mesmo a função?

eu neste momento tenho algo do genero:

$k = 0;
while ( my ($keyTemp, $valueTemp) = each(%tempHash) ) {
#		$temp = $keys[$k];
	for ($k=0;$k <= $sizeBlast;$k++){
		if ( $keys[$k] eq $keyTemp ){
			$count++;
			print "$keyTemp => $valueTemp: $count\n";
		}
	}
	$count = 0;
}

todas as variáveis e assim estão declaradas, e o resultado deste código é:

gi|213515420|ref|NP_001133374.1| => MSP01003598: 1

gi|167626813|ref|YP_001677313.1| => MSP01011189: 1

gi|241667394|ref|ZP_04754972.1| => MSP01011189: 1

gi|169633332|ref|YP_001707068.1| => MSP01011189: 1

gi|260798158|ref|XP_002594067.1| => MSP01003598: 1

gi|261856045|ref|YP_003263328.1| => MSP01011189: 1

gi|94676877|ref|YP_588963.1| => MSP01011189: 1

gi|167854832|ref|ZP_02477609.1| => MSP01011189: 1

gi|118100834|ref|XP_417476.2| => MSP01003598: 1

gi|262376190|ref|ZP_06069420.1| => MSP01011189: 1

gi|220934338|ref|YP_002513237.1| => MSP01011189: 1

gi|261253723|ref|ZP_05946296.1| => MSP01011189: 1

gi|126642017|ref|YP_001085001.1| => MSP01011189: 1

gi|91093144|ref|XP_969873.1| => MSP01003598: 1

mas não deveria ser assim, algo nos meus ciclos esta errado :hmm:


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
falco

O Perl não apaga!

Apaga se fizeres com que apague.

O grep recebe uma referência para um endereço que faz parte da lista/array em relação à qual o grep é invocado. Se alterares o valor referenciado então o array vai ser alterado.

Se tivesses testado o código que coloquei aí, verias que não houve qualquer alteração do array.

Se instalares o Data::Dumper, e modificares o código que coloquei aqui para isto:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @array = (1,2,3,4,5,6,1);
my @matchs = grep {/^1$/} @array; 
print "Found ".int(@matchs)."\n";
print "\n";

print "\@array dump:\n";
print Dumper \@array;

E executares o código, então vais ver que o array @array, não foi alterado.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
diokhan

adaptei o que disseste, obrigado pela ajuda

deixo aqui o código, caso alguém queira dar uma dica para melhorar ou se alguém precisar

my $temp = "";

my $o = 0;
$k = 0;
while ( $k <= $sizeBlast ) {
	$temp = $tempArray[$o];
	while ($o <= $sizeBlast){
		if ( $blast[0][$k][4] ~~ $temp ){
			my $matchs = grep { index($_, $temp) > -1}  @tempArray;
			my $int = int($matchs);
			print "$blast[0][$k][4] => $blast[0][$k][0] : $int\n";
			last;
		}
	}
	$count = 0;	
	$o++;
	$k++;
}


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
falco

Esquece lá esse teu código... É exageradamente complexo!

Em primeiro lugar não precisas de usar a função index dentro do grep, alias a sua utilização é pior solução que utilizar uma regexp como esta (e eu dei a dica): /^\Q$MyMatchPattern\E$/x

Para além disso o teu código não faz o que tu pediste. Não está a procurar as ocorrências de um valor num array, mas a contar o numero de ocorrências de cada valor diferente no array. E já te dei em outra thread uma solução muito melhor para isso.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.