Jump to content
  • 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

Recommended Posts

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...

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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 🤔


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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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...

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.