#!/usr/bin/perl -w
use strict;

# Aufruf: tfidf.pl  <STDIN  >STDOUT
# ---------------------------------
# Erzeugt zu einer tokenisierten Textdatei (STDIN) eine nach TF-IDF-Werten sortierte Liste 
# aller Terme (Token) und schreibt sie nach STDOUT.
# Im gleichen Verzeichnis wie das Skript tfidf.pl muss die df-Datei liegen!
#
# Die folgenden beiden Angaben sind notwendig:
# 1. Der df-Speicher (Ausgabe des Skripts df.pl):
my $df_datei = "wikipedia10K.df";
# 2. Die Anzahl der Dokumente aus denen der df-Speicher erzeugt wurde.
my $n = 10000;

# Zuerst den df-Speicher aus der df-Datei in ein Hash namens %DF einlesen.
my %DF; my $term; my $df;
open(DF, "<$df_datei") or die "Konnte $df_datei nicht oeffnen!\n";
while(<DF>){
    ($term, $df) = split;
    $DF{$term} = $df;
}
close(DF);

# Eingabedatei zeilenweise durchlaufen, Zeilen an Whitespace
# in Token zerlegen. Termfrequenzen in Hash %TF zaehlen.
my %TF; my @zeile; my $token;
while(<STDIN>){
    @zeile = split;
    foreach $token ( @zeile ){
	$TF{$token}++;
    }
}

# Zu allen Termen im Hash %TF die TF-IDF-Werte berechnen und im
# Hash %TFIDF speichern.
my %TFIDF; my $tfidf;
foreach $term ( keys %TF ){
    # Ist der Term bekannt (d.h. im Korpus, auf dessen Grundlage die df-Werte
    # bestimmt wurden, bereits vorgekommen)?
    if ( exists($DF{$term}) ){
	$df = $DF{$term};
    }else{
	$df = 0;
    }
    # TF-IDF fuer den Term $term berechnen
    $tfidf = $TF{$term} * log( $n / ($df + 0.1) );
    # und im Hash %TFIDF speichern
    $TFIDF{$term} = $tfidf;
}

# Hash mit Termen nach TF-IDF sortiert ausgeben 
foreach $term ( sort freqcompare keys %TFIDF ){
    print STDOUT "$term $TFIDF{$term}\n";
}

# Sortierfunktion. Variablen $a und $b sind global.
sub freqcompare {
    if($TFIDF{$a} > $TFIDF{$b}) {
        -1;
    } elsif ($TFIDF{$a} < $TFIDF{$b}) {
        1;
    } else {
        ($a cmp $b);
    }
}

