#!/usr/bin/perl -w
use strict;
use warnings;
my @bigramas;
my @C;
my $cantTerminos;
my $numPal = 1;
# Este método se encarga de encontrar la cantidad total de bigramas que posee cada hilera
# y mientras esto se realiza se calcula el total de bigramas únicos almacenando cada bigrama
# obtenido en una estructura hash. El propósito de usar un hash es porque se pueden almacenar
# en él los distintos bigramas pero permite evitar guardar repetidos, por lo que al final de la
# revisión de la hilera el tamaño o cantidad de elementos del hash será el total de bigramas compartidos.
sub obtenerBigramas{
my %bigramasUnicos;
my $palabra = shift; #Se obtiene el contenido del archivo
chomp($palabra);
my $tam = length($palabra);
print "Hilera$numPal = $palabra = ";
for(my $i = 0; $i < $tam-1; $i++) {
$bigramasUnicos{substr($palabra,$i,2)} = 1;
print substr($palabra,$i,2).(" ");
}
my $cantBigramNoUnicos = $tam -1;
print "= $cantBigramNoUnicos\n";
my $cant=scalar keys %bigramasUnicos;
#Cantidad de bigramas para esa palabra
my $cantBigramas = scalar keys %bigramasUnicos;
print "Bigramas Unicos = $cantBigramas\n\n";
undef %bigramasUnicos;
#Se guarda la palabra junto con el total de sus bigramas correspondientes
if($cantBigramas > 0){
my $cadenaBigramas = $palabra." ";
$cadenaBigramas = $cadenaBigramas.$cantBigramas;
#El vector @bigramas contiene todas las palabras junto con su total de bigramas
push(@bigramas, $cadenaBigramas);
$cantTerminos++;
}
$numPal++;
}
sub bigramasComp{
my $cadenaSij;
for(my $i = 0; $i < $cantTerminos-1; $i++) {
#Se obtiene la palabra($palabra1) y total de bigramas($tamPal1) de esa palabra
my ($palabra1,$tamPal1) = split(' ',$bigramas[$i]);
for(my $j = 1; $j < $cantTerminos; $j++) {
#Se obtiene la palabra($palabra2) y total de bigramas($tamPal2) de esa palabra
my ($palabra2,$tamPal2) = split(' ',$bigramas[$j]);
#Se procede a calcular cuantos bigramas compartidos tienen las palabras $palabra1 y $palabra2
#Ese valor será C
my $C = calcularBigComp($palabra1,$tamPal1,$palabra2,$tamPal2);
print "Cantidad de bigramas comunes = $C\n\n";
#Se concatenan las palabras, la cantidad de bigramas compartidos entre ellas, y la cantidad
#de bigramas de cada palabra
$cadenaSij = $palabra1.("/").$palabra2.("/&").$C.("-").$tamPal1.("-").$tamPal2;
push(@C,$cadenaSij);
}
}
}
#Este metodo se encarga de calcular la cantidad de bigramas compartidos para cada 2 palabras
#recibidas por parametros
sub calcularBigComp{
my ($palabra1,$tamPal1,$palabra2,$tamPal2) = @_;
my $bigramaTemp1;
my $bigramaTemp2;
my %hashTemp;
#Para la palabra 1 se obtiene el primer bigrama. Luego éste se compara con cada uno de
#los bigramas de la palabra 2. Los bigramas que comparten las palabras se almacenan en
#una estructura hash. Finalmente se retorna la cantidad de elementos del hash que es
#igual a la cantidad de bigramas compartidos(C).
for(my $cont1 = 0; $cont1 < $tamPal1; $cont1++) {
$bigramaTemp1 = substr($palabra1,$cont1,2);
for(my $cont2 = 0; $cont2 < $tamPal2; $cont2++) {
$bigramaTemp2 = substr($palabra2,$cont2,2);
#Se usa hash para evitar almacenar elementos repetidos.
if($bigramaTemp1 eq $bigramaTemp2){
$hashTemp{$bigramaTemp1} = 1;
}
}
}
return scalar keys %hashTemp;
}
#Este metodo se encarga de calcular el valor de similitud entre cada palabra.
#Sij = 2*C/(A+B)
sub calcularSij{
#@C contiene una cadena con las palabras i y j, su valor C, y total de bigramas compartidos(A y B)
foreach my $temp(@C){
my $temp2 =$temp;
$temp2 =~ s/\&([0-9]*(\-)?)*//g; #Se obtienen las palabras evaluadas
$temp =~ s/(.*?)\/\&//g; #Se obtienen los valores C,A y B
my ($C,$A,$B) = split('-',$temp);
my $sij = $temp2.(2*$C/($A+$B)); #Se concatenan las palabras con su valor Sij respectivo
print "Sij = $sij\n";
}
}
#Comienza a ejecutarse el programa.
my $continuar = "Si";
while($continuar eq "Si" || $continuar eq "si" || $continuar eq "SI"){
my $hilera1;
my $hilera2;
print "DISTANCIA CON N-GRAMAS USANDO BIGRAMAS\n\n";
print "Digite la hilera 1: ";
$hilera1 = <STDIN>;
chop($hilera1);
print "\nDigite la hilera 2: ";
$hilera2 = <STDIN>;
chop($hilera2);
print "\n";
chomp($hilera1);
obtenerBigramas($hilera1);
chomp($hilera2);
obtenerBigramas($hilera2);
bigramasComp();
calcularSij();
print "\n\nDesea calcular la distancia con bigramas para otras dos hileras(Si/No)? ";
$continuar = <STDIN>;
chop($continuar);
undef @bigramas;
undef @C;
$cantTerminos = 0;
$numPal = 1;
}
Comentarios sobre la versión: 1 (0)
No hay comentarios