Avatar billede alsvik Nybegynder
09. oktober 2008 - 22:01 Der er 18 kommentarer og
1 løsning

Bigram & Trigram

Jeg har brug for en en bigram og trigram tæller. Gerne en simpel PHP som kan benyttes online!

Bigram = "to ord"
Trigram = "tre sammenhængende ord"

I en given tekst, skal jeg kunne optælle liste antallet af de forskellige tri- og bigrams og vise dem i rækkefølge sorteret efter mest benyttet!


Kan nogen hjælpe?
Avatar billede jakobdo Ekspert
09. oktober 2008 - 22:18 #1
Da jeg ikke aner en dyt om hvad bigram og trigram er, kan du forklare det lidt nærmere ?
Avatar billede kjeldsted Novice
09. oktober 2008 - 22:24 #2
Er det korrekt forstået at du søger et script til at tælle/opliste alle de steder hvor der i en given tekst findes sætninger på hhv. 2 og 3 ord, eller hvad mener du med ovenstående?
Avatar billede alsvik Nybegynder
09. oktober 2008 - 22:43 #3
ja - jeg ønsker et program som kan finde alle strenge af 2 ord og 3 ord og optælle hvor mange gange de går igen.
Teksten: jeg vil gerne ha en is og jeg vil gerne købe en og vil gerne købe en til dig også.

Ville således give:
Bigrams
3 x vil gerne
2 x jeg vil
2 x købe en

Trigrams
2x  jeg vil gerne

I modsætning til ren ord optælling, kan bi- og trigrams give et bedre indtryk af indholdet af en tekst.
Avatar billede alsvik Nybegynder
09. oktober 2008 - 23:02 #4
der skal naturligvis tages højde for at bigrams og trigrams skal findes i hele sætninger og må altså ikke overskride et punktum. Kommaer er underordnet og kan blot fjernes før gennemløb, men både ; ! ? ; " skal opfattes som afslutning af en sætning. 
I bedste tilfælde kunne feks et punktum som indgår i et tal (10.000) opfattes som en del af ordet ...
Og der findes garanteret mange andre ting man kan/bør tage højde for.
Det bliver hurtigt lidt speget, ik?!
Avatar billede olebole Juniormester
10. oktober 2008 - 03:13 #5
<ole>

Det kunne sikkert gøres mere 'sexy', men det bliver ikke inat. Jeg har skiftet punktummer i tal ud med kommaer - dem må du selv skifte, hvis det er et problem  =)

<?php
$s = <<<STREND
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean risus nibh, sodales et, pellentesque vitae, condimentum quis, tortor.
Donec sed ipsum. Proin lobortis est a metus. Morbi ornare orci posuere lectus rhoncus libero.

Quisque ultricies risus. Cras fermentum tellus varius mauris. Phasellus nec pede vel dolor commodo fermentum.
Fusce blandit tellus feugiat nulla. Nullam nibh. Proin 10.000 venenatis orci nec nunc.
Phasellus feugiat, orci vel posuere euismod, urna orci posuere lectus, vel sodales elit urna nec nunc.
Nullam pretium mauris blandit tellus feugiat nulla sit amet dolor. Ut dictum.
STREND;

$s = preg_replace("/(,|\r|\n|\t)/", "", $s);
$s = preg_replace("/(\d+)\.(\d+)/", "$1,$2", $s);
$a = preg_split("/(\.|\!|\?|;|\")/", $s);

$aBiGrams = array();
$aTriGrams = array();
for ($i=0,$j=count($a); $i<$j; $i++) {
    $aLine = explode(" ", $a[$i]);
    $nLines = count($aLine);
    if ($nLines>=3) {
        for ($m=0,$n=$nLines; $m<$n-2; $m++) {
            if ($aLine[$m]!="" && $aLine[$m+1]!="" && $aLine[$m+2]!="") {
                $aTriGrams[] = $aLine[$m]." ".$aLine[$m+1]." ".$aLine[$m+2];
            }
        }
    }
    if ($nLines>=2) {
        for ($m=0,$n=$nLines; $m<$n-1; $m++) {
            if ($aLine[$m]!="" && $aLine[$m+1]!="") {
                $aBiGrams[] = $aLine[$m]." ".$aLine[$m+1];
            }
        }
    }
}

$aBiG = array();
for ($i=0,$j=count($aBiGrams); $i<$j; $i++) {
    if ( $aBiG[$aBiGrams[$i]] ) $aBiG[$aBiGrams[$i]] += 1;
    else $aBiG[$aBiGrams[$i]] = 1;
}
arsort($aBiG);

$aTriG = array();
for ($i=0,$j=count($aTriGrams); $i<$j; $i++) {
    if ( $aTriG[$aTriGrams[$i]] ) $aTriG[$aTriGrams[$i]] += 1;
    else $aTriG[$aTriGrams[$i]] = 1;
}
arsort($aTriG);

$sOut = "<div><b><u>Bigrammer:</u></b></div>";
foreach($aBiG as $key => $val) {
    $sOut .= "<div><b>".$key."</b> blev fundet ".$val." gang".($val>1?"e":"")."</div>";
}

$sOut .= "<hr><div><b><u>Trigrammer:</u></b></div>";
foreach($aTriG as $key => $val) {
    $sOut .= "<div><b>".$key."</b> blev fundet ".$val." gang".($val>1?"e":"")."</div>";
}

print $sOut;
?>

/mvh
</bole>
Avatar billede olebole Juniormester
10. oktober 2008 - 03:21 #6
Njahhh ... lidt mere 'sexy' kan du godt få den:

<?php
$s = <<<STREND
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean risus nibh, sodales et, pellentesque vitae, condimentum quis, tortor.
Donec sed ipsum. Proin lobortis est a metus. Morbi ornare orci posuere lectus rhoncus libero.

Quisque ultricies risus. Cras fermentum tellus varius mauris. Phasellus nec pede vel dolor commodo fermentum.
Fusce blandit tellus feugiat nulla. Nullam nibh. Proin 10.000 venenatis orci nec nunc.
Phasellus feugiat, orci vel posuere euismod, urna orci posuere lectus, vel sodales elit urna nec nunc.
Nullam pretium mauris blandit tellus feugiat nulla sit amet dolor. Ut dictum.
STREND;

$s = preg_replace("/(,|\r|\n|\t)/", "", $s);
$s = preg_replace("/(\d+)\.(\d+)/", "$1,$2", $s);
$a = preg_split("/(\.|\!|\?|;|\")/", $s);

$aBiGrams = array();
$aTriGrams = array();
for ($i=0,$j=count($a); $i<$j; $i++) {
    $aLine = explode(" ", $a[$i]);
    $nLines = count($aLine);
    if ($nLines>=3) {
        for ($m=0,$n=$nLines; $m<$n-2; $m++) {
            if ($aLine[$m]!="" && $aLine[$m+1]!="" && $aLine[$m+2]!="") {
                $sTmp = $aLine[$m]." ".$aLine[$m+1]." ".$aLine[$m+2];
                if ($aTriGrams[$sTmp]) $aTriGrams[$sTmp] += 1;
                else $aTriGrams[$sTmp] = 1;
            }
        }
    }
    if ($nLines>=2) {
        for ($m=0,$n=$nLines; $m<$n-1; $m++) {
            if ($aLine[$m]!="" && $aLine[$m+1]!="") {
                $sTmp = $aLine[$m]." ".$aLine[$m+1];
                if ($aBiGrams[$sTmp]) $aBiGrams[$sTmp] += 1;
                else $aBiGrams[$sTmp] = 1;
            }
        }
    }
}
arsort($aBiGrams);
arsort($aTriGrams);

$sOut = "<div><b><u>Bigrammer:</u></b></div>";
foreach($aBiGrams as $key => $val) {
    $sOut .= "<div><b>".$key."</b> blev fundet ".$val." gang".($val>1?"e":"")."</div>";
}

$sOut .= "<hr><div><b><u>Trigrammer:</u></b></div>";
foreach($aTriGrams as $key => $val) {
    $sOut .= "<div><b>".$key."</b> blev fundet ".$val." gang".($val>1?"e":"")."</div>";
}

print $sOut;
?>
Avatar billede olebole Juniormester
10. oktober 2008 - 03:24 #7
- og $nLines burde selvfølgelig have heddet $nWords, hvis der skulle være logik i tingene. I den variabel ligger antallet af ord i den aktuelle linje  =)
Avatar billede olebole Juniormester
10. oktober 2008 - 03:28 #8
- og en 'linje' er i denne forstand ikke en linje, men faktisk et punktum ... altså ikke tegnet punktum, men et antal ord mellem to skilletegn  ;D

- og så er det godnat, Ole!
Avatar billede jakobdo Ekspert
10. oktober 2008 - 06:18 #9
Sov godt Olebole, du er tydeligvis ved at være overtræt, du mangler jo din <ole> <bole> tags. :o)
Avatar billede alsvik Nybegynder
10. oktober 2008 - 09:21 #10
Super. Mange tak!
Så mangler jeg bare et svar fra Ole, så jeg kan give point!
Avatar billede olebole Juniormester
10. oktober 2008 - 11:05 #11
Godmorgen, Jakob ... gider du lige at validere, om syntaksen i kommentaren (10/10-2008 03:13:41) modsvarer den høje grad af velformethed, som forfatterens krop i vide kredse er kendt for? Jaja, det var osse tidligt på dagen  ;D

alsvik >> Selvtak. Nu har du i hvertfald en begyndelse, men når man roder med søgemønstre i form af RegExps, kan man ofte komme ud for at glemme noget i forudsigelserne for, hvad man kan komme ud for at skulle søge mellem. Det må vi så tage til den tid  =)
Avatar billede jakobdo Ekspert
10. oktober 2008 - 11:37 #12
olebole: Jeg kan sgu ikke gennemskue din kode lige nu. :o)
Avatar billede alsvik Nybegynder
10. oktober 2008 - 11:55 #13
Det ser helt fint ud OleBole. Tusind tak!!!
Avatar billede olebole Juniormester
10. oktober 2008 - 12:24 #14
jakobdo >> Det var osse bare en lille flabethed, vedr. mine ole-bole-tags ... de var der skam!  ;o)

alsvik >> Tak for points  =)
Avatar billede jakobdo Ekspert
10. oktober 2008 - 12:55 #15
olebole: Jaja, men ikke på de efterfølgende. Ergo syntax error. ;o)
Avatar billede olebole Juniormester
10. oktober 2008 - 16:25 #16
Jakob >> På dette _ene_ punkt er det mig - og _kun_ mig - der sætter standarden!  ;D

Kik i gamle tråde, og du vil opdage, at standarden siger: "Kun tags i første indlæg i en tråd" - og sådan har det vist været de seneste fem års tid  =)
Avatar billede jakobdo Ekspert
10. oktober 2008 - 17:34 #17
Olebole: Har du bare altid et rigtigt svar på alt ?
Avatar billede olebole Juniormester
10. oktober 2008 - 20:50 #18
Kendte engang en overordentlig alsidig musiker, som introducerede mig for mottoet: "If you can't fake it - you can't make it!"  ;D
Avatar billede olebole Juniormester
10. oktober 2008 - 20:52 #19
PS: Hun nævnte det dog ikke, før vi var blevet gift! *LoL*
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester