Pascal/Turbo Pascal - Programa para contar palabras

 
Vista:

Programa para contar palabras

Publicado por Víctor (3 intervenciones) el 28/12/2006 11:57:37
Hola a tod@s!

Estoy haciendo un programa que coge una frase, la separa en palabras y luego te dice cuantas palabras iguales hay en la misma frase....y no consigo hacer casi nada :S.

Consigo separar la primera palabra pero a la hora de introducirla en el array que me va a hacer de lista tengo problemas, a ver si podeis ayudarme, os lo agradecería infinito ^^.

El programa que he hecho es este:

-----------------------------------
PROGRAM palabras (INPUT, OUTPUT);

USES crt;

VAR frase,palabra: STRING;
n,i,a: INTEGER;
lis: ARRAY [1..255] OF STRING;
rep:ARRAY [1..255] OF INTEGER;
aux :BOOLEAN;

BEGIN
clrscr;
WRITELN ('Introduzca la frase y pulse ENTER para finalizar');
READLN (frase);
palabra:=''; //Pongo la variable "palabra" en cadena vacia
a:=1;
n:=1;

WHILE (n>LENGTH(frase)) DO

// La parte que viene selecciona las palabras. Funciona perfectamente

BEGIN
WHILE (frase[a]>='a') AND (frase[a]<='z') DO
BEGIN
palabra:=palabra+frase[a];
a:=a+1;
END;

// La parte que viene a continuación chequea si la palabra existe ya en el array lis que es el que contendrá las palabras o si el array lis en la posicion que está mirando está vacio.

i:=1;
WHILE aux=FALSE DO
BEGIN
IF palabra=lis[i] THEN aux:=TRUE
ELSE
BEGIN
IF lis[i]='' THEN aux:=TRUE ELSE
i:=i+1;
END;
END;

// Aqui iría la parte que, dependiendo de si la palabra ya se encuentra en el array lis sumaría en el array repe uno más (puesto que la palabra ya está repetida) o bien, si la posicion del array lis está vacia, le asignaría el valor de la variable "palabra" y pondría el array repe en 1 (para indicar que esta palabra está una vez. No funciona

IF (palabra=lis[i]) THEN (repe[i]:=repe[i]+1) ELSE
BEGIN
lis[i]:=palabra;
repe[i]:=1;
END;

n:=a+1;
a:=a+1;
palabra:='';
END;

READKEY;
END.
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:Programa para contar palabras

Publicado por Diego Romero (996 intervenciones) el 29/12/2006 03:36:20
Pregunto antes de meter la pata... ¿por qué debes almacenar las palabras en un array si ya las tienes en el string que el usuario ingresó?
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

RE:Programa para contar palabras

Publicado por micropais (209 intervenciones) el 29/12/2006 19:34:48
Saludos Víctor.
Te envio un fragmento de código para que te hagas una idea , de como prodria ser el programa que cuenta palabras , esta bien comentatdo , con algunos ligeros cambios podras ver que facil es contar palabras de un fichero .
este fragmento está comprobado bajo Free Pascal - espero que te sirva.
_______________________________________________________________


uses crt;
var cadena:string;

{----------------------------------------------------------------------------}
{busca en una cadena la siguiente aparicion relativa a la ultima busqueda del
caracter car a buscar , si no se encuentra el caracter separador,la funcion
devuelve un cero , si se encuentra el separador la funcion devuelve la
posicion relativa desde la ultima aparicion , esta posicion encontrada la
deberemos reintroducir como parametro ini en la misma funcion , hasta que ya
no queden mas coincidencias y la funcion devuelva un cero. }
function pos_str(cad:string;car:char;ini:byte):byte;
var cnt:byte;
longitud:byte;
{----------------------------------------------------------------------------}
begin
pos_str:=0;

longitud:=length(cad);

cnt:=ini;
repeat
cnt:=cnt+1;
if (cad[cnt]=car) then
begin
pos_str:=cnt-ini;
break;
end;
until (cnt>longitud) ;
end;
{----------------------------------------------------------------------------}

{----------------------------------------------------------------------------}
procedure trocear_frase(var cad:string;separador:char);
{----------------------------------------------------------------------------}
{ trocea una cadena en las palabras que la contienen , para ello busca
los separadores - normalmente el separador es el caracter espacio , pero se
puede usar cualquier otro separador.-
nota:el caracter separador no se incluye en el troceo
}
var
sig:byte; { siguiente posicion }
pos:byte; { posicion anterior para encontrar la siguiente posicion }
copy_ini:byte; { inicio de otra palabra }
copy_fin:byte; { final de otra palabra }
longitud:byte; { longitud de la cadena }

begin
longitud:=length(cad); { longitud de la cadena }
pos:=0; { posicion inicial debe ser 0 }

repeat
sig:=pos_str(cad,separador,pos);
if (sig=0) then break;
pos:=pos+sig;
copy_ini:=(pos-sig)+1;
copy_fin:=sig-1;
writeln ( copy(cad,copy_ini,copy_fin) ); { }
until (sig=0);
{____________________________________________________________________________
si cada palabra est  separada por espacios y la frase termina sin espacio
la ultima palabra queda delimitada por el fin de la cadena y la recogemos
____________________________________________________________________________}
copy_ini:=(pos-sig)+1;
writeln( copy(cad,copy_ini,longitud) ); { }

end;

{---------------------------- Programa Principal ---------------------------}
begin
clrscr;
cadena:='cadena de texto de tipo string maximo 255 caracteres ideal para leer lineas de un fichero ';
trocear_frase(cadena,' ');

readln;
end.
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

RE:Programa para contar palabras

Publicado por Victor (3 intervenciones) el 30/12/2006 01:20:14
Hola a los dos!

Lo primero muchisima gracias por la ayuda, realmente sois geniales. En cuanto a lo de para que necesito introducir las palabras en un ARRAY es por que lo que quiero hacer con las palabras, una vez troceada la frase, es decir cuantas palabras hay iguales. por ejemplo, si introduzco la frase:

" no se si es que si o es que no"

El resultado debería ser:

no 2
se 1
si 2
es 2
que 2
o 1

De manera que me diga cuantas palabras tengo iguales en la frase. De ahí mi idea de meterlo en un array, en realidad en dos, en el primero almacenaría cada una de las palabras en una posición del array y en el segundo guardaría el número de veces que cada cadena se repite.

Voy a probar con lo que me habeis dado y os comento, mientras tanto, feliz año y felices fiestas ^^

Y MUCHAS GRACIAS DE NUEVO!
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

RE:Programa para contar palabras

Publicado por Diego Romero (996 intervenciones) el 30/12/2006 16:33:38
En realidad mi pregunta era porque tengo otra forma de encarar el problema y por supuesto una solución distinta. Quizá se deba a que tengo otro paradigna de programación.

Mi idea es la siguiente.
Me parece obvio que la frase puesta en un string está separada por tokens, los cuales son el espacio en blanco y el fín de la cadena.
Entonces procedería a recorrer el string extrayendo las palabras hasta encontrar un token, una vez obtenida la palabra, busco una coincidencia en un array declarado así:

type

TPalabra=record
Palabra: string;
Cuenta: integer;
end;

TPalabras=array[1..N] of TPalabra;

Aunque lo ideal sería hacer una lista dinámica.
Si hay una coincidencia dentro del array, aumento el contador, si no la hay, agrego la palabra y pongo en uno el contador.

Todo esto dentro de un ciclo que finaliza cuando encuentro el token "fin de cadena".
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

RE:Programa para contar palabras

Publicado por Victor (3 intervenciones) el 31/12/2006 12:24:44
Hola Diego!!,

Muchas gracias por la respuesta, en realidad es la que yo tenia en mente desde un principio pero al hacer el procedimiento para buscar en el array es cuando encuentro el problema y es que no se como hacerlo, por que lo que hice fue hacer un WHILE del tipo:

"pal" es la cadena que he extraido de la frase.

n:=1

WHILE (pal<>TPalabras[n]) OR (TPalabra[n]=' ' ) {Esto es para que si encuentra un espacio en blanco en el ARRAY coloque la palabra.}
n:=n+2; {supongo que habrá que poner +2 por que el ARRAY que tu has creado es del tipp (palabra1, contador1, palabra2,contador2, ... , palabran, contadorn).}

{Si se sale del bucle WHILE es por que la palabra existe o por que hay un hueco en blanco (ergo no existe y hay que colocar la palabra en ese hueco y colocar un 1 en el contador).

IF (pal=TPalabras[n]) THEN (TPalabras[n+1]:=TPalabras[n]+1)
ELSE
BEGIN
Tpalabras[n]:=pal;
TPalabras[n+1]:=1;
END;

Pero esto no me funcionaba, por eso pensé en lo de los dos ARRAY, uno para las palabras y otro para el contador....ya estoy desesperado y no se uq ehacer XD.

Anyway , Feliz año!!!
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

RE:Programa para contar palabras

Publicado por Diego Romero (996 intervenciones) el 31/12/2006 21:08:47
Mmm... no entendí muy bien tu implementación, yo tenía pensado algo así. En primera hay que resolver el problema del parseo de tokens.

uses crt;
const
Tokens: set of char=[' '];

var
Frase: string;
Palabra: string;
P: integer;

function EsToken(c:char):boolean;
begin
EsToken:=c in Tokens;
end;

function TomarPalabra(S: string; var Pos:integer): string;
var
Result: string;
begin
Result:=''; { nueva palabra }
while (Pos<=Length(S)) and not EsToken(S[Pos]) do { mientras no se acabe el string y el caracter no es token }
begin
Result:=Result+S[Pos]; { tomo un caracter }
inc(Pos); { siguiente }
end;
inc(Pos); { me salto el token o el fin de cadena }
TomarPalabra:=Result; { devuelvo la palabra }
end;

begin { principal }
ClrScr;
Write('Frase: ');
ReadLn(Frase); { leo la frase }
if Length(Frase) > 0 then { si la frase no está vacía }
begin
P:=1; { evaluación posorden }
Palabra:='';
while P < Length(Frase) do { mientras haya caracteres }
begin
Palabra:=TomarPalabra(Frase, P); { tomo una palabra }
WriteLn(Palabra); { la muestro, aquí puedes poner la palabra en un array o hacer las comparaciones necesarias }
end; { while }
end; { if }
ReadKey;
end. { fin }
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