Pascal/Turbo Pascal - ES URGENTE!!

 
Vista:

ES URGENTE!!

Publicado por Andres (7 intervenciones) el 15/11/2006 00:00:19
Hola todo bien,les dejo la letra de una tarea que me piden hacer,la primera parte ya la hice.
La tarea se basa en un programa que ingresa texto escrito en teclado telefonico y despliegue su traduccion tecla por tecla.El programa aceptara texto escrito en las dos modalidades:Multitap y Prediccion por prefijos.
Multitap ya lo hice,en cambio prefijos no.-

Aca esta la letra de la tarea:

5. Predicción por prefijos
Se trabaja con la misma asociación de teclas que con multi-tap. En este método cada tecla entre 0 y 9 se pulsa una sola vez. El sistema adivina cuál es la letra más apropiada del conjunto de letras posibles, analizando el contexto previo. Si la letra elegida por el sistema no es la que el usuario pretendía, este puede solicitar otra elección utilizando la tecla *. Si el sistema de predicción es bueno, se supone que la tecla ‘*’ no va a ser utilizada muchas veces.

Ejemplo: Para escribir la frase

soy de la ciudad
se escribe lo siguiente:

7**6903*305202*4*8**323
La tecla * se pulsó 7 veces por lo que podríamos pensar que el sistema de predicción no es muy bueno. Sin embargo la cantidad de teclas pulsadas es claramente menor que en el método multi-tap.

5.1 Frecuencias relativas a prefijos
Suponemos que disponemos del conjunto de todas las palabras que se utilizan en el lenguaje (vocabulario). A partir de ese vocabulario se puede construir una tabla de frecuencias que nos diga cuantas veces una letra c aparece siguiendo a una secuencia xyz de 3 letras en todas las palabras del vocabulario. Esas frecuencias serán útiles para realizar la predicción.

También vamos a necesitar las frecuencias para los prefijos de menos de 3 letras, cuando la letra que se necesita predecir es primera, segunda o tercera de una palabra.

Notación: FR(p,c) es la cantidad de veces que aparece c a continuación del prefijo p en las palabras del vocabulario. Si p tiene menos de 3 letras solo se consideran las apariciones al comienzo de la palabra, es decir que la palabra comienza con p y sique con c. Si p tiene 3 letras, consideramos todas las apariciones

5.2 Cómo se realiza la predicción
Supongamos que hasta el momento se ingresó un texto T

y que el usuario digita la tecla d que tiene asociados los caracteres a1,a2, . . .,am

El método que se utiliza para predecir la letra es el siguiente:

Se toman los 3 últimos caracteres de la última palabra de T. Si esta palabra tiene menos de 3 caracteres se toman los que haya (2, 1 o 0). Esta secuencia de hasta 3 caracteres es el prefijo corriente. Llamemos p a esta cadena.
Se busca en la tabla los valores de las frecuencias FR(p,ak) para cada uno de los ak posibles.
Se elige el ak que tenga la frecuencia máxima
Cuando el usuario pulsa * se cambia la letra elegida por la que le sigue en frecuencia. También aquí se alterna de manera circular entre las letras posibles. Es decir que luego de pulsar m veces la tecla * se retorna a la primera elección.

Un ejemplo de predicción basada en prefijos:

>>> P7**6903*305202*4*8**323
7 ->r
* ->p
* ->s
6 ->so
9 ->soy
0 ->soy
3 ->soy e
* ->soy d
3 ->soy de
0 ->soy de
5 ->soy de l
2 ->soy de la
0 ->soy de la
2 ->soy de la a
* ->soy de la c
4 ->soy de la ch
* ->soy de la ci
8 ->soy de la cit
* ->soy de la civ
* ->soy de la ciu
3 ->soy de la ciud
2 ->soy de la ciuda
3 ->soy de la ciudad
>>>

La tabla de frecuencia de prefijos
Vamos a utilizar prefijos de hasta 3 caracteres. Por lo tanto nuestra tabla de frecuencias podría ser una matriz de 4 dimensiones:

type
letra = 'a'..'z';
TipoTabla = array [letra,letra,letra,letra] of integer
Si tenemos una variable tabla con tipo TipoTabla, entonces tabla[x,y,z,c] nos da la frecuencia de apariciones de la cadena xyz precediendo al caracter c.

La representación anterior está incompleta porque no considera que los prefijos pueden tener entre 0 y 3 caracteres. Solamente se guardan los prefijos de 3 caracteres.

Para considerar los prefijos de 0 a 2 caracteres vamos a introducir un caracter ficticio que llamaremos el carácter nulo.

const
nulo:= '{';
Y luego definimos un nuevo tipo que es la extensión de las letras con el carácter nulo:

type
letra = 'a'..'z';
letraX = 'a'..nulo;
Notar que la elección del carácter ‘{’ como carácter nulo se hace debido a que es el sucesor de la ‘z’ (de otra forma no podríamos definir el rango letraX).

El carácter nulo nos provee una forma de representar todos los prefijos con exactamente 3 caracteres: si un prefijo tiene menos de 3 caracteres, se rellena con nulos por la izquierda hasta completar los 3.

La tabla de frecuencias se define finalmente, como sigue:

TipoTabla = array [letraX,letraX,letraX,letra] of longint;
Hemos cambiado integer por longint ya que vamos a necesitar números superiores a maxint.

Los prefijos
Por lo dicho en la sección anterior, un prefijo se va a representar como un arreglo de tres caracteres:

type TPrefijo = array [1..3] of char;Es conveniente definir un procedimiento que obtenga el prefijo corriente a partir del mensaje:

procedure ObtenerPrefijo(msj : mensaje; ultimo: integer; var prefijo: TPrefijo);También es posible evitar este procedimiento, actualizando el prefijo cada vez que se agrega un carácter al mensaje. Hay que tener en cuenta que cada vez que se agrega un espacio el prefijo se hace vacío.

El diccionario
El diccionario es un archivo de texto que contiene una palabra por línea. Este archivo no contiene palabras con tildes, diéresis, mayúsculas ni eñes.

Para leer un archivo de texto en pascal se debe hacer lo siguiente:

1) Declarar el archivo como una variable de tipo text

var
diccio: text;
2) Asociar la variable declarada con la ruta en disco correspondiente al archivo:

assign(diccio,'diccionario.txt');
En este caso, suponemos que el archivo está en el mismo directorio que el programa.

3) Preparar el archivo para iniciar la lectura

reset(diccio);Las instrucciones assign y reset deben ir al comienzo del programa antes de comenzar a leer del archivo. Luego de eso, están disponibles las mismas operaciones que se utilizan para leer de la entrada estándar. Por ejemplo:

read(diccio,car) lee un carácter del archivo diccio.
readln(diccio) consume todos los caracteres hasta el fin de línea
eoln(diccio) es true si se consumieron todos los caracteres de una línea y queda el fin de línea.
eof(diccio) es true si se consumieron todos los caracteres del archivo diccio.
Para ilustrar el manejo de archivos de texto, presentamos un ejemplo donde se lee completamente el diccionario y se calcula el largo de la palabra más grande:

program MaxPalabra;
var
diccio : text;
car : char;
max,largo : integer;
begin
{ apertura del archivo }
assign(diccio,'diccionario.txt');
reset(diccio);

{inicialización}
max:= 0;
while not eof(diccio) do
begin
{comienza lectura de la línea}
largo:= 0;
while not eoln(diccio) do
begin
read(diccio,car);
{incrementa contador}
largo:= largo+1;
end;
readln(diccio); {limpia el fin de línea}
{terminó la línea, actualiza el maximo}
if largo > max then
max:= largo;

end;
{terminó el archivo}
{se muestra el resultado}
WriteLn('La palabra más larga tiene ',max,' caracteres');
end.
En la tarea se deberá hacer una recorrida similar del diccionario pero con el objetivo de cargar la tabla de frecuencias de prefijos.

Secuencias de caracteres
Ya se ha explicado que cada tecla de 0 a 12 tiene asociado una secuencia de caracteres. Decimos secuencia y no conjunto porque el orden es relevante. Estas secuencias son de diferentes largos: la tecla 1 tiene 10 símbolos, mientras que la 5 tiene sólo 4. Vamos a utilizar un arreglo de caracteres para representar estas secuencias:

type secuencia = array [0..10] of char;Pero se necesita una manera de indicar que en algunos casos habrá menos de 10 caracteres en el arreglo. Para esto vamos a utilizar un centinela que es un carácter no válido que indica el fin de la secuencia. Por ejemplo para representar la secuencia asociada con la tecla 5:

j k l 5 $ . . .

Estamos usando como centinela el carácter ‘$’. A tales efectos conviene definir una constante:

const CENTINELA = '$'; Observar que se ha definido el índice del arreglo comenzando desde 0. El objetivo de esto es facilitar la recorrida circular de la secuencia utilizando el operador mod.

Las secuencias se utilizan en ambos métodos. En multitap se recorren en el orden preestablecido; en prefijos se ordenan por frecuencia. En ambos casos se recorren circularmente.

Puede resultar de utilidad las funciones:

function largo(s : secuencia): integer;
{retorna el largo de la secuencia }

function ObtenerCaracter(s: secuencia, i: integer): char;
{
retorna el caracter que se encuentra en la posición i dentro de la secuencia
si i>largo(s) lo resuelve circularmente
}

Ordenamiento por frecuencia
En el método multitap la secuencia asociada con una tecla se recorre en el orden preestablecido en la configuración del teclado. En cambio en la predicción por prefijos se debe recorrer de acuerdo con las frecuencias de cada caracter relativas al prefijo existente. Para esto conviene definir un procedimiento que realice el ordenamiento:

procedure OrdenarSecuencia(tabla : TablaF; prefijo: TPrefijo; var s: secuencia);

Esquema general
El pseudo-código del programa principal puede ser como sigue:

cargar tabla de frecuencias
repeat
mostrar prompt;
LeerCaracter(car);
case car of
'P' : procesar prefijos;
'M' : procesar multitap;
'F' : termina:= true;
else
saltear línea;
end;
until termina;

Si alguien me puede hacer el codigo se lo agradesco mucho.
Gracias.-
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:ES URGENTE!!

Publicado por Santiago (2 intervenciones) el 15/11/2006 04:25:06
hola andres q haces? supongo q seras de la facultad de ingenieria de montevideo pq yo tengo el mismo problema q vos, bah, en realidad mi problema es mucho peor pq ni siquiera se como arrancarla. Te jode a vos ayudarme? Pasarme lo q hiciste y yo lo cambio para q no parezca copia
gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar