• Publicidad

Eliminar ítem vector

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Eliminar ítem vector

Notapor dacons » 2006-05-12 03:22 @181

Hola, ¿qué tal?

Tengo un programa que recorre un vector y compara las palabras para contar el número de veces que aparece cada palabra, el problema está en que luego quiero meter en una lista la palabra y el número y no quiero que salgan palabras repetidas.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for ( $i = 0; $i <= $#@palabras; $i++ ) {
  2.     $cont = 0;
  3.     for ( $j = 0; $j <= $#@palabras; $j++ ) {
  4.         if ( $palabra[$i] eq $palabra[$j] ) {
  5.             $cont++;
  6.         }
  7.     }
  8. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
pero así saldrían repetidas. ¿Cómo puedo eliminar las palabras que ya he contado?
dacons
Perlero nuevo
Perlero nuevo
 
Mensajes: 48
Registrado: 2006-02-27 04:15 @219

Publicidad

Notapor explorer » 2006-05-12 06:08 @297

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á:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use warnings;
  3. @palabras = do { open F, "<kk.txt"; <F> };
  4. for ( $i = 0; $i <= $#palabras; $i++ ) {
  5.     next if $palabras[$i] eq "";
  6.     $cont = 1;
  7.     for ( $j = $i + 1; $j <= $#palabras; $j++ ) {
  8.         if ( $palabras[$i] eq $palabras[$j] ) {
  9.             $cont++;
  10.             $palabras[$j] = "";
  11.         }
  12.     }
  13.     print "La palabra $palabras[$i] sale $cont veces\n";
  14. }
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:
Sintáxis: [ Descargar ] [ Ocultar ]
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í:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -l
  2. use warnings;
  3. use strict;
  4.  
  5. my @palabras = do { open F, "<kk.txt"; <F> };
  6. my %palabras_unicas;
  7.  
  8. foreach my $palabra (@palabras) {
  9.     chomp $palabra;
  10.     $palabras_unicas{$palabra}++;
  11. }
  12.  
  13. foreach my $palabra ( sort keys %palabras_unicas ) {
  14.     print "La palabra $palabra sale $palabras_unicas{$palabra} veces";
  15. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
obtenemos como salida:
Sintáxis: [ Descargar ] [ Ocultar ]
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.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor dacons » 2006-05-12 07:59 @374

Ya lo solucioné, pero con los dos for anidados y otro vector con un copia de las palabras ya leídas.

Tu explicación es muchísimo más sencilla y más eficiente que lo que yo he hecho,

Muchísimas gracias una vez más.
dacons
Perlero nuevo
Perlero nuevo
 
Mensajes: 48
Registrado: 2006-02-27 04:15 @219


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 26 invitados