El array de palabras lo recorres en dos bucles anidados, por lo que es posible que te encuentres, efectivamente, contando palabras que habías visto en la pasada anterior.
Una forma de arreglarlo primero es que el bucle interior no recorra desde el principio del
array, sino en la palabra siguiente a la que estamos analizando:
for ( $j = $i + 1; $j <= $#palabras; $j++ ) {para evitar duplicaciones, pero estaríamos con el mismo problema en cuanto a las posibles palabras duplicadas que existan al final del
array.
Una forma de resolverlo puede ser esta: cada vez que encontremos una palabra igual a la que estamos buscando, la borramos:
$palabras[$j] = "";y de esa manera no la contaremos cuando el bucle principal llegue a su nivel.
Naturalmente, hay que tener en cuenta dos cosas: el
array queda modificado y, además, hay que saltarse la comprobación de elementos nulos:
next if $palabras[$i] eq "";Si no nos preocupa que el vector quede modificado, entonces la solución será:
Using perl Syntax Highlighting
#!/usr/bin/perl
use warnings;
@palabras = do { open F, "<kk.txt"; <F> };
for ( $i = 0; $i <= $#palabras; $i++ ) {
next if $palabras[$i] eq "";
$cont = 1;
for ( $j = $i + 1; $j <= $#palabras; $j++ ) {
if ( $palabras[$i] eq $palabras[$j] ) {
$cont++;
$palabras[$j] = "";
}
}
print "La palabra $palabras[$i] sale $cont veces\n";
}
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Si nos interesa mantener el
array, lo que podemos hacer es que antes de entrar en el bucle, copiamos ese
array a otro:
@copia = @palabras;De todas formas, en Perl, este problema es el mejor ejemplo para mostrar el funcionamiento de las variables
hash, pues le vienen muy bien a este caso.
Si tenemos un fichero kk.txt:
Using text Syntax Highlighting
abobábamos
abobaban
abobabais
abobabas
abobad
abobada
abobado
abobadas
abobados
abobaban
abobabais
abobabas
abobad
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
entonces con un programa así:
Using perl Syntax Highlighting
#!/usr/bin/perl -l
use warnings;
use strict;
my @palabras = do { open F, "<kk.txt"; <F> };
my %palabras_unicas;
foreach my $palabra (@palabras) {
chomp $palabra;
$palabras_unicas{$palabra}++;
}
foreach my $palabra ( sort keys %palabras_unicas ) {
print "La palabra $palabra sale $palabras_unicas{$palabra} veces";
}
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
obtenemos como salida:
Using text Syntax Highlighting
La palabra abobabais sale 2 veces
La palabra abobaban sale 2 veces
La palabra abobabas sale 2 veces
La palabra abobad sale 2 veces
La palabra abobada sale 1 veces
La palabra abobadas sale 1 veces
La palabra abobado sale 1 veces
La palabra abobados sale 1 veces
La palabra abobábamos sale 1 veces
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Explicación:en la línea 5 leemos el fichero y lo metemos en el
array. En la línea siguiente definimos la variable
hash que nos guardará las palabras únicas.
En el bucle de las líneas 8 a 10 recorremos el
array, quitamos el final de línea de cada palabra (
chomp) y la guardamos en el
hash, aumentando en uno (++) las veces que aparece. Si es una palabra repetida, lo que estamos haciendo es incrementar ese valor de
hash en uno.
En el siguiente bucle, pintamos las palabras que hemos encontrado, ordenadas alfabéticamente (
sort) junto con las veces que aparecen.