[SP-pm] Duvida com Hashes

Andre Carneiro andregarciacarneiro at gmail.com
Tue Apr 20 16:55:47 PDT 2010


Linha 1 - declarando variáveis...
Linha 2 - Recuperando entrada via teclado, armazenando em @words sem o
terminador(quem tira o terminador é chomp - veja em perldoc -f chomp). #
Terminador nesse caso = caracter que representa o 'enter'  - \n no UNIX
                 No entanto, você precisa fazer CTRL+D para parar de colocar
coisas dentro de @words.

Linha 3 - Iniciando a Iteração(laço) do array @words
Linha 4 - Para cada iteração, se você digitar a mesma palavra, perl vai
acrescentar 1 a um contador cuja a chave é a palavra que você digitou.
Linha 5 - Termina a iteração do array @words.
Linha 6 - Inicia a iteração do hash %count que foi preenchido entre as
linhas 3 e 5. Aqui, utiliza-se foreach + a função 'keys', passando como
parâmetro o hash %count.(Sem o parênteses fica esquisito??? keys %count
idêntico a keys(%count) ok??? Em Perl vc pode suprimir parênteses em algumas
ocasiões.  Voltando, keys nesse caso, está retornando uma chave do hash a
cada iteração, ou seja, se você tiver um hash assim:

<code>
my %count = ( 'palavra1' => 2,
                           'palavra2' => 1,
                           'palavra3' => 4,
                         );

</code>

keys retornará a cada iteração, respectivamente: 'palavra1', 'palavra2',
'palavra3'. Mais detalhes na documentação:  perldoc -f keys

Linha 7 - Aqui você já está apto a imaginar o que acontece. As palavras são
as chaves(cada valor retornado por 'keys' em cada iteração). Se você tem as
chaves, para obter os valores, basta passar a chave para o hash retornar, ou
seja, '$count{$word}' . Por que não %count{$word} ???? Em Perl 5, para obter
um valor qualquer do hash, vc precisa que isso esteja em contexto escalar.
Isso em Perl é representado por $ e não por %. Mais detalhes sobre isso veja
em:  perldoc perlintro.

Linha 8 - Finalizando a iteração.


Complicou???


O código abaixo está um pouco menos  'alienígena', embora o código seja
mais longo. No entanto faz a mesma coisa e explica mais detalhadamente o que
acontece.
             <code>
                        my(@words, %count, $word,$w); #declarando
variaveis...
                        my $continue='s'; #inicializando $continue, com um
valor coerente com as mensagens mais abaixo...
                        while($continue eq 's'){

                               #apenas uma mensagem
                               print "\nESCREVA ALGO: ";

                                #capturando uma palavra via entrada-padrão
                               $w = <STDIN>;

                               #retirando o terminador (\n se UNIX). Por
que? Porque senão vc inclui o 'enter' na palavra. Aqui não faria diferença,
mas se vc precisasse comparar $w com outra string qualquer poderia ser um
problema, se a outra string não tivesse o terminador também. Por definição,
retire os terminadores...
                               chomp $w;

                               #inserindo as palavras no array
                               push @words, $w;

                                #Fazendo a contagem de palavras. Como você
está passando a palavra que vc digitou como chave, e relacionando isso a um
contador, toda a vez que você repetir isso na iteração, perl vai incrementar
o contador no lugar certo, ou seja, toda a vez que vc digitar a mesma
palavra, o contador será acrecido(ou acrescido)... de um.
                               $count{$w} += 1;

                               #critica para continuar(ou não), a inserir
palavras. Aqui é a mensagem. A linha de baixo armazena a resposta da crítica
em $continue...
                               #lembre-se que $continue foi inicalizado com
o valor 's' mais acima. Se você digitar 'ENTER', sem escrever nada, 's'
continuará sendo o valor de $continue
                               print"\nOUTRA PALAVRA?(s/n)[s]: ";

                               # Aqui define-se se você vai ou não continuar
digitando palavras.
                               $continue=<STDIN>;

                               #retira o terminador \n. Por que?  Repare no
while ---->   while($continue eq 's') ... Isso significa que ele vai
comparar continue com 's', e não com "s\n", entendeu?
                               chomp $continue;
                          }

                       #percorrendo o hash %count. Você pode fazer isso de
outra maneira usando a função 'each'. Veja em perldoc -f each.
                       # $word vai receber a cada iteração uma chave do hash
%count. Portanto para obter cada valor em %count em uma iteração, basta
utlizar '$count{$word}', como já mencionado acima.
                        foreach $word (keys %count) {
                             print "$word was seen $count{$word} times.\n";
                        }
               </code>


Espero ter sido claro.


Cheers!






2010/4/18 "Flávio R. Lopes" <flavio.lopes at links.inf.br>

>  Pessoal, no livro que estou lendo, mais especificamente no capítulo que
> trata de Hashes, tem um exercício proposto em que o autor pede para elaborar
> um programa em que o usuário digita palavras (nomes, por exemplo) e o
> sistema tem que contar quantas vezes foram digitados as mesmas palavras.
>
> Abaixo segue a solução apresentada pelo autor:
>
> 1    my(@words, %count, $word);
> 2    chomp(@words = <STDIN>);
> 3    foreach $word (@words) {
> 4    $count{$word} += 1;
> 5    }
> 6    foreach $word (keys %count) {
> 7      print "$word was seen $count{$word} times.\n";
> 8    }
>
>
> Nas linhas de 3 a 5 é "armazenado" o número de vezes que uma palavra
> aparece, ou seja, é feita uma contagem, certo?
>

Você testou esse código?


> Agora é aqui que não entendi direito (nas linhas de 6 a
> 8)....especificamente no trecho *(keys %count)* O que fiquei em dúvida se
> é aqui que é "montado" o Hash, ou seja, os valores são "captados" nas linhas
> de 3 a 5 e depois "transportados" ou "armazenados" no Hash *%count* da
> linha 6 ??, pois os valores digitados pelo usuário são armazenados no Array
> @words, contados nas linhas de 3 a 6 e "armazenados" no hash *%count* ???
>
> Não sei se fui claro, mas como é o raciocínio disto?...Vcs poderia me
> ajudar a ler e entender este código?
>
> abraço,
> Flávio
>
> _______________________________________________
> SaoPaulo-pm mailing list
> SaoPaulo-pm at pm.org
> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>



-- 
André Garcia Carneiro
Analista/Desenvolvedor Perl
(11)82907780
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20100420/d276f84c/attachment.html>


More information about the SaoPaulo-pm mailing list