












































Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Asignatura: Pràctiques de Programació, Profesor: , Carrera: Eng. Tècnica d'Informàtica de Sistemes, Universidad: UPC
Tipo: Apuntes
1 / 52
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!













































El disseny modular es basa en construir una sèrie de mòduls de dades o funcionals que ens permetin resoldre un problema determinat. La descomposició en mòduls que realitzem estarà principalment basada en les dades. És a dir, per fer la descomposició modular del problema, primer analitzarem quins tipus de dades s’han de manegar per a resoldre el problema. Aquestes dades seran abstractes, no seran en la majoria de casos tipus de dades existents, com ara piles o vectors, sino que introduirem nous tipus de dades, com ara Estudiant, i les seves operacions associades que creguem necessàries. Posteriorment, treballarem la seva implementació, que en molts casos estarà basada en tipus de dades, ara si, coneguts, com ara piles, vectors, etc. Per aconseguir una veritable modularitat, és molt impor- tant mantenir aquesta idea de tipus abstractes de dades. Per exemple, suposem que volem tractar un text analitzant-lo paraula per paraula. Hom podria pensar ràpidament en utilitzar els vectors de caràcters com a tipus de dades per tractar el text. Ara bé, depenent del tractament pot ser millor considerar piles de caràcters o una altra estructura. És a dir, nosaltres sabem que necessitem “Paraules” i que les podem implementar a posteriori amb vectors, piles, etc. Aquest és el fet que ha de guiar el nostre disseny modular. Detectar quins tipus de dades necessitem, com ara Paraula, i dotar-los de les operacions que considerem necessàries per resoldre el nostre problema. Per suposat, els tipus nous poden estar relacionats entre ells: per exemple podem necessitar el tipus “Grup de paraules” i el tipus Paraula, cadascun amb les seves operacions. També és possible que inicialment hagim proposat alguna operació que finalment no sigui necessària, o bé, que ens n’hagim deixat alguna. Tot això ho detectarem a mida que avanci el disseny. En aquest sentit, l’estratègia de disseny es pot veure com una contínua “negociació” entre el que estem dissenyant i el que encara no hem dissenyat. Per exemple, si féssim un disseny descendent “pur”, proposariem l’algorisme de més alt nivell sense haver especificat encara cap mòdul. Els mò- duls ens apareixerien “a petició” de l’algorisme que estiguéssim dissenyant (hi ha una dependència algorisme mòduls). Si féssim un disseny ascendent “pur”, primer proposariem uns mòduls concrets i després intentariem usar-los en l’algorisme (aquí tendriem una dependència mòduls algorisme). En ambdós casos, una mala decisió sobre el que estem dissenyant podria perjudicar el que encara no ha estat dissenyat. La solució passa per fer un procés iteratiu que incrementalment vagi refinant els diferents mòduls de l’aplicació i que eviti certes decisions prematures en el disseny. Per exemple, primer podem tenir una certa intuició sobre quines coses farà l’algorisme principal (fem una mica de disseny descendent). A continuació proposem uns mòduls (principalment de dades) amb operacions que ens ajudin a refinar aquesta idea intuitiva de l’algorisme que volem dissenyar (fem una mica de disseny ascendent). A continuació refinem l’algorisme. Pot passar que:
Ara repetiriem el procés per refinar els mòduls. En general, és millor refinar primer els mòduls que són més amunt en la jerarquia de mòduls que hem creat (els més propers al programa principal). Refinar un mòdul requereix implementar el tipus i les seves operacions. Per fer això, novament primer establiríem de manera aproximada l’estrategia de resolució de les operacions, a la vegada que pen- saríem la millor implementació del tipus que ens ajudi a aconseguir la millor implementació de les
Començariem el procés iteratiu de refinament amb una certa intuició sobre com treballaria l’al- gorisme principal: hem de llegir paraules, les hem de guardar, hem de saber si una paraula ja ha aparegut, hem de saber quantes vegades ha aparegut cada paraula, etc. Per concretar fem una primera aproximació del que serà el programa principal:
Esquema de programa principal:
llegir paraula mentre no final fer afegir paraula llista llegir paraula fmentre calcular PSI
Basant-nos en aquesta intuició, fem una primera proposta dels mòduls que ens agradaria tenir. Per exemple:
Ens agradaria tractar amb paraules i no pas amb caràcters i fer operacions com comparar paraules. Ens agradaria tenir una “base de dades” ( llista de paraules ) on poder-hi fer consultes com saber si una paraula està a la llista o saber quantes vegades ha aparegut. Ens agradaria treballar sobre una seqüència de paraules enlloc d’una seqüència de caràcters, i tenir operacions com llegir una paraula de la seqüència.
Basant-nos en aquesta intuició, fem la proposta de definir tres nous mòduls. En un primer nivell, només especificarem les operacions que podrem fer amb aquest mòduls. Noteu que en el disseny real del nostre programa, inicialment vem decidir treballar amb “paraules” encara que no teniem una idea clara de quines operacions necessitariem. La necessitat d’alguna de les operacions com la de “comparar paraules” ens va aparèixer quan desenvolupavem les operacions de “llista de paraules”. De tota manera, aquí presentem les especificacions totals dels tres mòduls.
Modul Paraula;
Especificacio
{ Tipus de modul: dades }
Tipus paraula;
{ Descripcio general: conte una paraula que es una serie de lletres }
Operacions
funcio comparar_paraules (p1, p2: paraula) retorna igual: boolea {Pre: - } {Post: igual = "p1 i p2 son iguals"}
funcio es_buida (p: paraula) retorna b: boolea {Pre: - } {Post: b = "p es la paraula buida"}
La funció es_buida potser que no la considerem al principi i l’afegim quan considerem les se- qüències de paraules, per detectar el final de seqüència. No hem inclòs una operació per copiar paraules, encara que en orientació a objectes si la ne- cessitariem. En els dissenys sobre paper, usarem sempre l’assignació, si volem copiar el valor d’una variable del tipus que sigui en una altra variable (del mateix tipus). En canvi, com es veurà a laboratori, en Java haurem d’afegir a les nostres especificacions una operació de còpia. De fet, en llenguatges no orientats a objectes, segons com implementeu els nous tipus que dissenyeu, també pot caldre afegir una operació de còpia, però aquestes qüestions ja es consideran en el següent curs.
Modul Sequencia_paraules;
Especificacio
Sobre Paraula;
{ Tipus de modul: dades }
Tipus seq_paraules;
{ Descripcio general: es una estructura que ens permet obtenir paraules sequencialment }
Operacions
accio obrir_sequencia_paraules (e/s s: seq_paraules) {Pre: s esta tancada} {Post: s esta oberta i preparada per llegir el primer element}
accio llegir_paraula (e/s s: seq_paraules; sort p: paraula) {Pre: s esta preparada per llegir una paraula} {Post: p es la paraula que s estava preparada per llegir, s esta preparada per llegir la seguent paraula. En el cas que es trobi amb ’#’, p es la paraula buida}
accio tancar_sequencia_paraules (e/s s: seq_paraules) {Pre: s esta oberta} {Post: s esta tancada}
Una vegada definits els mòduls que utilitzarem, podem refinar l’algorisme principal.
algorisme var S: seq_paraules; {La sequencia d’entrada} L: llista_paraules; {La base de dades de paraules} p: paraula; {Paraula actual llegida de la sequencia} psi: real; {Resultat de l’experiment}
inicialitzar_llista_paraules (L); obrir_sequencia_paraules (S); llegir_paraula (S, p);
{Inv: L conte les frequencies de totes les paraules llegides de S, excepte de la darrera paraula emmagatzemada a p} mentre no es_buida (p) fer afegir_paraula (L,p); llegir_paraula (S, p); fmentre;
tancar_sequencia_paraules (S);
{L conte totes les paraules llegides de S amb la seva frequencia} psi:=PSI(L); escriure (psi); fi_algorisme;
En la presentació de la solució d’aquest exemple ens hem saltat una de les iteracions en el refinament successiu. En particular, en la primera solució haviem proposat la funció
funcio freq_paraula (L: llista_paraules; p: paraula) retorna f: enter {Pre: - } {Post: f es la frequencia de la paraula p a la llista L}
enlloc de la funció PSI. Després ens en vem adonar que això no ajudava massa l’algorisme principal degut a que en algún moment hauriem de recórrer la llista L, element a element, per calcular β. Així doncs vem preferir amagar aquest recorregut dins d’una operació PSI del mòdul llista_paraules. Aquest és un exemple de la "negociació" entre el que estem dissenyant i el que hem de dissenyar. Cada vegada que refinem (en aquest cas, l’algorisme principal), podem reconsiderar algunes decisions que hem près anteriorment. No s’ha de considerar aquest “tirar enrera” com un error de disseny, sino com una decisió natural en el procés de disseny modular. De fet, en general, és difícil encertar completament el disseny dels mòduls (tipus i operacions) “a la primera”. Per tant, encara que en la majoria d’exemples presentarem una solució completa a la primera, s’ha d’entendre que en el procés d’obtenir-la és més que possible que hagim realitzat algunes iteracions en el disseny.
En aquesta secció es prendran decisions d’implementació. Aquest és un problema senzill i la imple- mentació triada és en tots els casos bastant natural. De tota manera, en el procés d’implementació d’un dels mòduls cometrem “voluntàriament” un error que ens permetrà mostrar un dels errors més usuals en el disseny modular. Per solventar aquest problema haurem de modificar el nostre disseny. Per tant, això també ens servirà per il lustrar una iteració en el procés de disseny. Durant la implementació inclourem comentaris sobre les decisions preses, així com la derivació informal dels algorismes iteratius. Al final presentarem la implementació completa. Començarem per els mòduls que estan més amunt en la jerarquia de mòduls que hem creat. Tant Sequencia_paraules com Llista_freq_paraules usen Paraula, però no tenen cap relació entre ells. Començarem per Sequencia_paraules. Noteu que si treballéssim en grup es podria realitzar el desenvolupament dels tres mòduls en paral lel, tenint en compte que el mòdul Paraula pot requerir noves operacions.
2.5.1 El mòdul Sequencia_paraules
Modul Sequencia_paraules;
Implementacio
Sobre Paraula;
tipus seq_paraules = sequencia de caracter;
Operacions
accio obrir_sequencia_paraules (e/s s: seq_paraules) {Pre: s esta tancada}
obrir_sequencia (s);
{Post: s esta oberta i preparada per llegir el primer element}
accio llegir_paraula (e/s s: seq_paraules; sort p: paraula) {Pre: s esta preparada per llegir una paraula}
saltar_blancs(s); p.long := 0; {Inv: p.cars[1..p.long] conte els caracters llegits de la paraula actual de la sequencia s} mentre actual(s) =/= ‘ ’ /\ actual(s) =/= ‘#’ fer p.long := p.long + 1; p.cars[p.long] := actual(s); avancar(s) fmentre;
{Post: p es la paraula que s estava preparada per llegir, s esta preparada per llegir la seguent paraula.
{Post: p s’ha modificat afegint-li el caracter c al final }
funcio comparar_paraules (p1, p2: paraula) retorna igual: boolea {Pre: - } {Post: igual = "p1 i p2 son iguals"}
funcio es_buida (p: paraula) retorna b: boolea {Pre: - } {Post: b = "p es la paraula buida"}
En aquest cas, el canvi en el mòdul paraula no afecta a res més del disseny ja que només hem afegit operacions. Seguim ara amb el disseny del mòdul Sequencia_paraules. En aquest mòdul no inclourem les derivacions dels algorismes iteratius, ja que en tots els casos es tracta d’operacions d’entrada/sortida. Per això, només inclourem els invariants com a comentaris als programes.
Modul Sequencia_paraules;
Implementacio
Sobre Paraula;
tipus seq_paraules = sequencia de caracter;
Operacions
accio obrir_sequencia_paraules (e/s s: seq_paraules) {Pre: s esta tancada}
obrir_sequencia (s);
{Post: s esta oberta i preparada per llegir el primer element}
accio llegir_paraula (e/s s: seq_paraules; sort p: paraula) {Pre: s esta preparada per llegir una paraula}
saltar_blancs(s); p:=paraula_buida(); {Inv: p conte els caracters llegits de la paraula actual de la sequencia s} mentre actual(s) =/= ‘ ’ /\ actual(s) =/= ‘#’ fer afegir_lletra(actual(s),p); avancar(s) fmentre;
{Post: p es la paraula que s estava preparada per llegir, s esta preparada per llegir la seguent paraula. En el cas que es trobi amb ’#’, p es la paraula buida (longitud = 0)}
accio saltar_blancs (e/s s: seq_paraules); {Pre: s esta preparada per llegir una paraula}
{Inv: s esta preparada per llegir una paraula} mentre (actual(s) = ‘ ’) fer avancar (s); fmentre;
{Post: s esta preparada per llegir una paraula i l’element actual de s no es un blanc }
accio tancar_sequencia_paraules (e/s s: seq_paraules) {Pre: s esta oberta}
tancar_sequencia (s);
{Post: s esta tancada}
Noteu que l’acció saltar_blancs és una operació interna de la implementació, que no es pot usar fora d’aquest mòdul. Si volguéssim fer-la pública l’hauriem d’incloure a l’especificació. És molt possible que al implementar un mòdul ens calgin noves operacions ocultes, ja que per questions de legibilitat s’ha d’evitar tenir operacions implementades amb algorismes molt llargs. A més, és important que al implementar una operació apliqueu, quan calgui, l’abstracció funcional. Recordeu que l’abstracció funcional consisteix bàsicament en considerar que, si en un cert moment ens cal una operació que no tenim, p.e. una que salti blancs, podem suposar que la tenim (i li donem nom i una especificació) i després, un cop hagim acabat, la implementem.
2.5.2 El mòdul Llista_paraules
Modul Llista_paraules;
Implementacio
Sobre Paraula;
tipus llista_paraules = tupla nparaules: enter; paraules : vector [1..MAXSUBJ] de tupla par: paraula; freq: enter {frequencia d’aparicio de la paraula} ftupla; ftupla;
Noteu que, novament, com a decisió d’implementació (seguint l’indicació de l’enunciat) hem imposat un límit màxim en el nombre de paraules diferents que poden apareixer en el text. En aquesta implementació hem descrit la llista amb una tupla amb un camp (nparaules) que ens indica el nombre de paraules a la llista i un camp (paraules) que és un vector de tuples que contenen la paraula (par)
Noteu que ara que coneixem l’implementació del tipus, hem canviat l’especificació de la operació, afinant-la respecte a la implementació. Per exemple, la precondició reflecteix les limitacions derivades d’haver implementat la llista amb un vector. Això no comporta problemes de correcció, doncs les condicions de l’enunciat permeten garantir el seu cumpliment. Anem ara a implementar l’operació oculta que haviem deixat pendent. Es tracta d’una cerca. Com a invariant, considerem que no hem trobat la paraula en les posicions anteriors a l’actual i que si el boolea b és cert llavors és que en la posició actual està la paraula que busquem.
funcio cerca_paraula (L: llista de paraules; p: paraula) ret b: boolea; i: nat; {Pre: - }
i := 1; b := fals; {Inv: "p no apareix a L a les posicions [1..i-1]" , b => "i conte la posicio de la taula on esta p" , 1 <= i <= L.nparaules + 1 } mentre !b /\ i <= L.nparaules fer si comparar_paraules (p,L.paraules[i].par) llavors b := cert sino i := i+1; fsi; fmentre;
{Post: b = "p apareix a L" , b => i conte la posicio de la taula on esta p }
Donem alguns detalls de la derivació: Inicialitzacions. Posant un 1 a la i (que està en el domini de valors fixat), satisfem que p no apareix a les posicions anteriors. A més, posem b a fals, ja que llavors no s’ha de satisfer res més. Condició de sortida. Hi ha dos posibilitats per sortir. (1) Si b és cert, ja que llavors sabem que la paraula és a la posició i. A més, el booleà b ja té el valor correcte (satisfà la postcondició). (2) Si b és fals però la i és L.nparaules+1, ja que llavors sabem que la paraula no apareix. A més, novament, el booleà b ja té el valor correcte. Per tant, la condició del bucle és la negació dels dos casos, és a dir, !b i i <= L.nparaules (noteu que i sempre és menor o igual que L.nparaules+1). Cos del bucle. L’invariant que hem triat està inspirat en l’ús del boolea b com a marca quan trobem la paraula cercada. Per tant, el primer que fem és preguntar per la posició i-èssima. Si coincideix amb la paraula p, llavors posant b a cert satisfem un altre cop l’invariant, ja que fins a i-1 ja sabiem que no apareixia i, a més, ara es satisfà que quan b és cert la paraula apareix a la posició i. En cas contrari, si p no coincideix amb la paraula de la posició i, llavors sabem que fins la posició i no apareix p (i com que b és fals no cal satisfer res més). Per tant, podem incrementant la i satisfent l’invariant. Acabament. A cada volta, o bé b passa de fals a cert (i sortim del bucle), o bé b no canvia i llavors decreix la distància entre L.nparaules+1 i la i.
Finalment, considerem la funció PSI. Per fer-ho, primer obtenim la màxima freqüència de les paraules de la llista (β) i el total de paraules (comptant repetits) que hem tractat en la llista, és a dir, la suma de les freqüències de les paraules (que coincideix amb el nombre de persones que han intervingut en l’experiment). Per acabar, calculem el factor PSI a partir d’aquests dos resultats parcials.
funcio PSI (L: llista de paraules) retorna psi: real {Pre: L.nparaules > 0 }
var beta, n, i: enter; i := 2; beta := L.paraules[1].freq; n := beta;
{Inv: n conte la suma de frequencies de les paraules [1..i-1] d’L, beta conte la frequencia maxima de les paraules [1..i-1] d’L, 1 <= i <= L.nparaules+1}
mentre i <= L.nparaules fer var f: enter; f := L.paraules[i].freq; n := n + f; si f > beta llavors beta := f; fsi; i := i+1; fmentre; { n conte la suma de frequencies de les paraules d’L, beta conte la frequencia maxima de les paraules d’L}
psi:= beta/n;
{Post: psi = factor PSI de L}
Anem a mostrar la derivació informal de l’algorisme. Inicialitzacions. Considerem que el conjunt buit no té definit un màxim. Llavors, la primera freqüència màxima que es pot calcular correspon al cas i=2 i serà la de la primera paraula, que assignarem a beta. Així mateix, la suma de freqüències pel cas i=2 es també la de la primera paraula i l’assignem a n. Noteu que aquest raonament es basa en que la llista no es buida. Condició de sortida. Com que volem tenir al final tota la llista tractada, sortirem del bucle quan i=L.nparaules+1. Per tant, ens quedem mentre i <= L.nparaules (noteu que l’invariant ens assegura que i <= L.nparaules+1). Cos del bucle. Com que hem d’avançar, el més natural és incrementar la i de manera que s’acosti al final del vector. Però abans d’incrementar la i, hem de tractar la paraula i-èssima, a fi de seguir garantint l’invariant. Necessitem, per tant, que n contingui finalment la suma de freqüències de les paraules en [1..i] d’L i beta la freqüència màxima de les paraules [1..i] d’L. Com que actualment n conté la suma de [1..i-1] i beta el màxim de [1..i-1], un cop guardat a la variable nova f la freqüència de la paraula i-èssima, hem de sumar f a n i mirar si f és el nou màxim o no. Si f és més gran que beta llavors f és el nou màxim ja que per transitivitat f és més gran o igual que totes les freqüències de les paraules en [1..i] d’L. En cas contrari beta segueix sent el màxim en [1..i]. Un cop que tenim la suma i el màxim fins a i, podem incrementar la i per tornar a tenir l’invariant fins i-1. Acabament. A cada volta decreix la distància entre L.nparaules+1 i la i.
{ p1.long = p2.long } igual := cert; i := 1; { Inv: p1.cars[1..i-1] = p2.cars[1..i-1], !igual => p1.cars[i] != p2.cars[i], 1 <= i <= p1.long+1} mentre igual /\ i <= p1.long fer si p1.cars[i] != p2.cars[i] llavors igual := fals; sino i := i+1; fsi; fmentre; fsi;
{Post: igual = "p1 i p2 son iguals"}
El primer condicional es basa en el fet de que si dues paraules són iguals han de tenir la mateixa longitud. Per tant, si no tenen la mateixa longitud no poden ser iguals. En cas contrari, comencem el procés iteratiu. Considerem com a invariant que totes les posicions fins a i-1 són iguals i que si el booleà igual és fals llavors la lletra i-èssima és diferent (noteu que si el booleà és cert llavors no sabem res de la lletra). A més, afegim el domini de valors que pot prendre la i. Anem a mostrar la derivació de les instruccions del bucle.
Inicialitzacions. Inicialment considerem que no hem comparat cap lletra, això ho representem posant un 1 a la i (que està en el domini de valors fixat), ja que així tenim que totes les posicions fins i-1 són iguals ja que no n’hi ha cap. A més, posem igual a cert, ja que llavors no s’ha de satisfer res més. Condició de sortida. Hi ha dos posibilitats per sortir.
Així doncs, com que volem sortir quan igual és fals o la i és p1.long+1 ens quedarem en cas contrari, és a dir quan igual i i <= p1.long (noteu que i sempre és menor o igual que p1.long+1). Cos del bucle. L’invariant que hem triat està inspirat en l’ús del boolea igual com a marca quan trobem dos elements diferents. Per tant, el primer que fem és preguntar per la posició i-èssima. Si són diferents, llavors posant igual a fals satisfem un altre cop l’invariant, ja que fins a i-1 ja sabiem que eren iguals i a més ara es satisfà que quan igual és fals les posicions i-èssimes són diferents (noteu que a continuació sortirem del bucle). En cas contrari, si la posició i és igual en les dues paraules, llavors sabem que fins la posició i totes les lletres són iguals (i com que igual és cert no cal satisfer res més). Per tant, incrementant la i satisfem l’invariant i avancem en el tractament dels vectors. Acabament. A cada volta, o bé igual passa de cert a fals (i sortim del bucle), o igual no canvia i llavors decreix la distància entre p1.long+1 i la i.
La implementació de l’última funció es basa en el fet de que una paraula és buida si i només si la seva longitud és zero.
funcio es_buida (p: paraula) retorna b: boolea {Pre: - }
b:= (p.long = 0)
{Post: b = "p es la paraula buida"}
2.5.4 Disseny complet
Com que es tracta del primer exemple, mostrarem tot el disseny. En la resta d’exemples no ho farem.
Especificació dels mòduls
Modul Paraula;
Especificacio
{ Tipus de modul: dades }
Tipus paraula;
{ Descripcio general: conte una paraula que es una serie de lletres }
Operacions
funcio paraula_buida () retorna p: paraula {Pre: - } {Post: p es una paraula buida}
accio afegir_lletra (ent c: caracter; e/s p: paraula); {Pre: - } {Post: p s’ha modificat afegint-li el caracter c al final }
funcio comparar_paraules (p1, p2: paraula) retorna igual: boolea {Pre: - } {Post: igual = "p1 i p2 son iguals"}
funcio es_buida (p: paraula) retorna b: boolea {Pre: - } {Post: b = "p es la paraula buida"}
Modul Sequencia_paraules;
{Post: L esta buida}
accio afegir_paraula (e/s L: llista de paraules; ent p: paraula) {Pre: - } {Post: L conte una nova aparicio de p}
funcio PSI (L: llista de paraules) retorna psi: real {Pre: L conte almenys una paraula } {Post: psi = factor PSI de L segons definit a l’enunciat del problema}
Algorisme
var S: seq_paraules; {La sequencia d’entrada} L: llista_paraules; {La base de dades de paraules} p: paraula; {Paraula actual llegida de la sequencia} psi: real; {Resultat de l’experiment} fvar
inicialitzar_llista_paraules (L); obrir_sequencia_paraules (S); llegir_paraula (S, p);
{Inv: L conte les frequencies de totes les paraules llegides de S, excepte de la darrera paraula emmagatzemada a p} mentre no es_buida (p) fer afegir_paraula (L,p); llegir_paraula (S, p); fmentre;
tancar_sequencia_paraules (S);
{L conte totes les paraules llegides de S amb la seva frequencia}
escriure (PSI(L)); fi_algorisme;
Implementació dels mòduls
Modul Paraula;
Implementacio
tipus paraula = tupla cars: vector [1..MAXLONG] de caracter; long: enter; ftupla
Operacions
funcio paraula_buida () retorna p: paraula {Pre: - }
p.long:=
{Post: ens retorna a p una paraula buida}
accio afegir_lletra (ent c: caracter; e/s p: paraula); {Pre: p.long < MAXLONG }
p.long:= p.long + 1; p.cars[p.long]:= c
{Post: p s’ha modificat afegint-li el caracter c al final }
funcio comparar_paraules (p1, p2: paraula) retorna igual: boolea {Pre: - } var i: enter;
si p1.long != p2.long --> igual := fals [] p1.long = p2.long --> { p1.long = p2.long } igual := cert; i := 1; { Inv: p1.cars[1..i-1] = p2.cars[1..i-1], !igual => p1.cars[i] != p2.cars[i], 1 <= i <= p1.long+1} mentre igual /\ i <= p1.long fer si p1.cars[i] != p2.cars[i] llavors igual := fals; sino i := i+1; fsi; fmentre; fsi;
{Post: igual = "p1 i p2 son iguals"}
funcio es_buida (p: paraula) retorna b: boolea {Pre: - }
b:= (p.long = 0)
{Post: b = "p es la paraula buida"}