Top tien van woorden

Hints voor de workshop deelnemers

Top tien van woorden

Berichtdoor Rob » za jan 26, 2008 3:54 pm

Hallo,

Ik wil even een idee voorleggen voor een programma. Het moet een tekst bekijken en uitrekenen welke woorden daarin het vaakst voorkomen. Woordfrequenties berekenen, oftewel een top tien maken van de meest populaire woorden (het woord "de" maakt een goede kans om koploper te zijn...)

Het Windows-venster zal een invoer-veld voor tekst moeten hebben (zelf intikken of kopiëren via klembord), een knop om het tellen te starten en een uitvoer-veld, waarin de woorden staan met hun score, de hoogste score bovenaan. Ik denk dat de woorden in twee (grote) array's kunnen worden opgeslagen, één voor de woorden en één voor de bijbehorende teller.

Het splitsen van regels of een hele tekst in losse woorden roept de vraag op wàt een woord is. Wat begrenst een woord? Als "delimiters" dringen zich in elk geval "begin van de regel", spatie, tab en "einde van de regel" (CR + LF) op. Ook leestekens als punt, komma, dubbel aanhalingsteken, haakjes, puntkomma en dubbele punt. Sommige tekens zijn soms een probleem: liggend streepje (zee-egel), apostrof (auto's), slash (1/2)...

Tenslotte zou het tellen moeten gebeuren zonder acht te slaan op hoofdletters (Tenslotte en tenslotte zijn het zelfde woord). En woorden van één letter kunnen buiten beeld blijven (anders zou "i.v.m." de woorden "i", "v" en "m" opleveren).

Wie ziet er wat in?

groeten,
rob bishoff
Rob
 
Berichten: 7
Geregistreerd: do nov 22, 2007 3:53 pm
Woonplaats: Amstelveen

Re: Top tien van woorden

Berichtdoor Abcott » za jan 26, 2008 4:03 pm

Lijkt mij een prima oefening voor jullie cursus.
Ik zal ook een poging wagen.

Jammer genoeg kan ik zelden aanwezig zijn op zo een
"workshop". Ik zou dat weleens willen meemaken.

Abcott.
Avatar gebruiker
Abcott
 
Berichten: 115
Geregistreerd: wo mei 25, 2005 9:58 pm

Re: Top tien van woorden

Berichtdoor Rob » zo feb 17, 2008 2:12 pm

Ik heb niet precies een 'top tien' geschreven, maar parser.bas lijkt er wel een beetje op. Toen ik met een redelijk groot tekstbestand aan het testen was, bleek de snelheid een rol te gaan spelen

Het programma parser.bas zoekt uit hoe vaak een woord in een bestand staat. Elk nieuw woord wordt in een groot array gezet, terwijl in een tweede array een teller wordt bijgehouden hoe vaak het woord is aangetroffen. In het oorspronkelijke programma wordt het array doorlopen op zoek naar een woord. Als het nieuw is, wordt het array nogmaals doorlopen op zoek naar een lege plaats. Dit is tijdrovend. Het programma doet er bv. 18 minuten over om de eerste tien hoofdstukken van de Max Havelaar te verwerken. Als het programma zichzelf verwerkt kost dat 22 seconden. In deze versie wordt weliswaar uit de lussen gesprongen zodra het zoeken resultaat heeft, maar er worden nodeloos veel rondjes gedraaid.

In parser2.bas is geprobeerd om efficiënter te werken. Het doorzoeken van het array naar een lege plaats voor een nieuw woord in namelijk helemaal niet nodig. Het eerst aangetroffen woord kan rechtstreeks in array$(0) gezet worden, het tweede in array$(1) enzovoort. Dit kan simpel worden bijgehouden in een tellertje 'volgende'. Ook hoeft het array bij het doorzoeken van de reeds gevonden woorden niet verder te zoeken dan deze variabele, want daarna is alles nog leeg. Met parser2.bas kost Max Havelaar "nog maar" 10 minuten en over zichzelf doet het programma 1 à 2 seconden.

Als ik af ga op de Max Havelaar staat het woord 'de' op de eerste plaats: 1599 keer, waar nog 537 keer de vervoegde vorm 'den' bij kan worden opgeteld. Daarna en (1257), van (954), ik (891) en dat (871). De Lauriergracht wordt 17 keer genoemd, waarvan 15 keer met het huisnummer 'No 37'. (Totaal 253003 bytes, 42902 woorden, waarvan 6977 verschillende).

De snelheid kan nog verder worden opgevoerd. Ik heb het programma ook in Visual Basic geschreven, met het algoritme van de eerste versie. Dit programma jast die tien hoofdstukken er in 10 seconden doorheen.

Hierbij de beide Just Basic-versies. Een grafisch interface is erbij ingeschoten.

groeten, rob bishoff
Bijlagen
parser.bas
(5.32 KiB) 193 keer gedownload
parser2.bas
(5.79 KiB) 175 keer gedownload
Rob
 
Berichten: 7
Geregistreerd: do nov 22, 2007 3:53 pm
Woonplaats: Amstelveen

Re: Top tien van woorden

Berichtdoor Gordon » zo feb 17, 2008 8:45 pm

Hallo Rob,

Hierbij een listing waar je misschien wat aan hebt.
Code: Selecteer alles
filedialog "open","c:\*.txt",bestand$

if bestand$ <> "" then
open bestand$ for input as #m
txt$ = input$(#m, lof (#m))
  token$ = "@"
  while token$ <> ""
      index = index + 1
      token$ = word$(txt$, index)
  wend
end if
close #m

print index


dim array$(index+1)
for t = 1 to index
      token$ = word$(txt$, t)
      print token$
      array$(t) = token$
next t

sort array$(),1,index

for t = 1 to index
print array$(t)
next t

start = 1

[f]
if t = index then end
b=0
for t = start to index
if array$(t) <> array$(t+1) then print "t= ";t:exit for
if array$(t) = array$(t+1) then b=b+1
scan
next

print b+1   ;" stuks ";array$(t)

start = t+1 : goto [f]
wait



Ik doe ook een les hierbij.

Gordon.
Bijlagen
les8.zip
dit bestand is in lesson-bestandsvorm
(1.14 KiB) 179 keer gedownload
Laatst bijgewerkt door Gordon op zo feb 17, 2008 8:50 pm, in totaal 1 keer bewerkt.
Reden: les erbij gedaan
Avatar gebruiker
Gordon
Site Admin
 
Berichten: 684
Geregistreerd: zo mei 22, 2005 12:50 am

Re: Top tien van woorden

Berichtdoor Gordon » ma feb 18, 2008 10:24 am

Code: Selecteer alles
filedialog "open","c:\*.txt",bestand$

if bestand$ <> "" then
open bestand$ for input as #m
txt$ = input$(#m, lof (#m))
  token$ = "@"
  while token$ <> ""
      index = index + 1             'het aantal woordjes
      token$ = word$(txt$, index)
  wend
end if
close #m


dim array$(index+1)
for t = 1 to index
      token$ = word$(txt$, t)
      array$(t) = token$        'alle woordjes in een array
next t
sort array$(),1,index           'alles sorteren


dim barray$(index,2)
start = 1
[f]
if t = index then [ok]
b=0
for t = start to index
if array$(t) <> array$(t+1) then exit for   'paar voor paar
if array$(t) = array$(t+1) then b=b+1       'checken
scan
next
q=q+1
barray$(q,1)= using("##",str$(b+1))         'aantal in barray
barray$(q,2)= array$(t)                     'woord  in barray
start = t+1 : goto [f]
wait

[ok]
sort barray$(),index,1,1                    'sorteren
for t = 1 to 10
print barray$(t,1),barray$(t,2)          'resultaat tonen
next



Gordon
Avatar gebruiker
Gordon
Site Admin
 
Berichten: 684
Geregistreerd: zo mei 22, 2005 12:50 am

Re: Top tien van woorden

Berichtdoor Rob » ma feb 18, 2008 2:02 pm

Hallo Gordon,

Dank voor je reacties.

Jammer genoeg geeft het bij mij een runtime error.

Oorzaak volgens mij onder het label [f]:
[f]
if t = index then [ok]

Als het laatste element is verwerkt is t=index-1, en niet t=index. Dus wordt de sprong niet gemaakt en wordt vergeleken met een element dat buiten de grenzen van array$() ligt. Een regel

if start = index then [ok]

werkt wel: start wordt namelijk met 'start = t + 1 : goto [f]' juist wel gelijk gemaakt met index.

Verder heb ik nog wat aanmerkingen.

Sort werkt niet in Just Basic. Dat is trouwens niet zo erg, want een sorteerroutine is makkelijk te schrijven.

Vervelender is dat het programma stevig steunt op de functie word$ om de invoer in woorden op te delen. Daardoor komen er allerlei losse tekens in de uitvoer en komt bv. "barray$(index,2)" als woord in de uitvoer. Ik wil juist de keuze van delimiters in eigen hand houden. Haakjes en komma zijn bij mij ook scheidingstekens, zodat barray$ en index zouden overblijven (2 wordt als los teken weggegooid). Ook worden "voorbeeld" en "voorbeeld," als aparte woorden geteld.

groeten, rob bishoff

p.s. Ik heb nog wat zitten sleutelen aan het slot (van je eerste programma). Meegestuurd als attachment.
Bijlagen
token_alt.bas
(1.66 KiB) 188 keer gedownload
Rob
 
Berichten: 7
Geregistreerd: do nov 22, 2007 3:53 pm
Woonplaats: Amstelveen


Keer terug naar Workshop Windows leren programmeren met Liberty BASIC

Wie is er online

Gebruikers op dit forum: Geen geregistreerde gebruikers. en 1 gast

cron