[ Foro de Pascal ]

Contar las repeticiones de cada letra en una palabra.

03-Apr-2012 22:47
Luis Torres (+18)
11 Respuestas

¿Alguien me podría indicar la manera en la que puedo contar cada letra en una palabra?. Se los agradecería. Saludos.


04-Apr-2012 22:53
Sam Garcia

Que tal !
En este caso con el objetivo de contar cada letra en una palabra se me ocurrio este algoritmo:
1) Ordenar la cadena, para que las letras iguales queden juntas
2) Utilizar un contador para determinar la cantidad de veces que    aparece cada letra.

Adicional a eso propongo convertir toda la cadena a mayusculas, pero esto podria omitirse dependiendo el uso que se le de.

Utilize el metodo de la burbuja para ordenar -es el unico que tenia en mente-, pero eso tambien se puede mejorar.

Este es el codigo:


program contar_letras;
var
	cadena:string;
	c:char;
	x,y,cuenta:byte;
	
(* el procedimiento lo utilizamos en la ordenacion *)
procedure intercambio(var a,b:char);
var aux:char;
begin
	aux:=a;
	a:=b;
	b:=aux;
end;
begin
	write('Ingresa una palabra : ');
	readln(cadena);
	(* Estandarizamos a todas las letras en mayusculas *)
	for x:=1 to length(cadena) do
		cadena[x]:=upcase(cadena[x]);
	(* Ordenar la cadena, en este caso con la burbuja*)
	for x:=1 to (length(cadena)-1) do
		for y:=x+1 to length(cadena) do
			if cadena[x]>cadena[y] then
				intercambio(cadena[x],cadena[y]);
	(* Ya que tenemos las letras iguales juntas utilizamos un contador *)
	cuenta:=1;
	c:=cadena[1];
	for x:=2 to length(cadena) do
	begin
		if c=cadena[x] then
			cuenta:=cuenta+1
		else
		begin
			writeln('Letra: ',c,' aparece ',cuenta,' veces.');
			c:=cadena[x];
			cuenta:=1;
		end;
	end;
end.


Ojala pueda ayudarte en algo.
Chau!


05-Apr-2012 02:07
Luis Torres (+18)

Muchas gracias por tu respuesta, Sam, eres muy amable en responder. Estuve probando tu programa pero sabes que introduje la palabra "palabra" y el resultado fue el siguiente:

Letra: A aparece 3 veces.
Letra: B aparece 1 veces.
Letra: L aparece 1 veces.
Letra: P aparece 1 veces.

Como ves, faltó la letra R.

Saludos.


05-Apr-2012 09:49
Sam Garcia

Tienes razon Luis.
El codigo tiene una evidente inconsistencia, procurare probar muchas veces mas los codigos que quiera publicar. En este caso el detalle esta dentro del ciclo For en donde se pone en marcha el contador. Y es que, como veras, cada vez que hay un cambio de letra de realiza los siguiente: 1) Se imprime la letra y el total anterior 2) Se cambia la letra y reinica el contador.

Y el problema es que la variable cambia a la R o la ultima letra que queda en la cadena, y se inicia su conteo, pero el valor nunca se imprime pues no hay otra distinta.

Por lo tanto creo que se solucionara colocando un ultimo Writeln que imprima el valor que quedo, y esto se haria despues de terminar el ciclo, del siguiente modo :


program contar_letras;
var
	cadena:string;
	c:char;
	x,y,cuenta:byte;
	
(* el procedimiento es para ustilizar el metodo de ordenacion *)
procedure intercambio(var a,b:char);
var aux:char;
begin
	aux:=a;
	a:=b;
	b:=aux;
end;
begin
	write('Ingresa una palabra : ');
	readln(cadena);
	(* Estandarizamos a todas las letras en mayusculas *)
	for x:=1 to length(cadena) do
		cadena[x]:=upcase(cadena[x]);
	(* Ordenar la cadena, en este caso con la burbuja*)
	for x:=1 to (length(cadena)-1) do
		for y:=x+1 to length(cadena) do
			if cadena[x]>cadena[y] then
				intercambio(cadena[x],cadena[y]);
	(* Ya que tenemos las letras iguales juntas utilizamos un contador *)
	cuenta:=1;
	c:=cadena[1];
	for x:=2 to length(cadena) do
	begin
		if c=cadena[x] then
			cuenta:=cuenta+1
		else
		begin
			writeln('Letra: ',c,' aparece ',cuenta,' veces.');
			c:=cadena[x];
			cuenta:=1;
		end;
	end;
	writeln('Letra: ',c,' aparece ',cuenta,' veces.'); (*Aqui se solucionaria el problema*)
end.


Espero haberte ayudado y no complicado en este problema.
Gracias por el aviso de este error.

Saludos!


05-Apr-2012 14:22
Fulanito de Tal

Hola. Esta es la solución que he encontrado yo.
Me ha dado un poquito de lata pero lo he conseguido.
Como la palabra se almacena en una variable string,
puede contener hasta 256 caracteres, con lo cual se puede
introducir un texto pequeño. En ese caso se cuentan todos los caracteres,
letras, números, signos varios, etc.
Como los espacios en blanco, si los hay, no se ven en la presentación, se añade la palabra "Espacios".


program contar_letras;

uses
	crt;

type
	tletras = record
		letra: char;
		cantidad: byte;
		end;

var
	palabra: string;
	longitud: byte; //Longitud de la palabra (número de caracteres)
	letras: array[1..256] of tletras; //Akí se almacenan las letras ya contadas
	tam_letras: byte; //Esta es la cantidad de letras almacenadas en el vector letras
	no_repetidas: byte;
	bucle1, bucle2: byte;
	auxiliar: tletras; //Esta variable es para ordenar los resultados

begin

clrscr;

writeln ('CONTAR LETRAS');
writeln ('-------------');
writeln;

write ('Teclea la palabra: ');
readln (palabra);

longitud := length (palabra);

//La primera letra de la palabra se almacena en el vector letras
letras[1].letra := palabra[1];
letras[1].cantidad := 1;

//Y por tanto ese vector tiene ya una letra almacenada
tam_letras := 1;

//En el bucle1 se van recorriendo todos los caracteres
//de la palabra introducida, excepto el primero.
//Para cada caracter se recorren (con el bucle2) en el vector letras todos los
//caracteres para ver si el nuevo ya está dentro

for bucle1 := 2 to longitud do
begin
	no_repetidas := 0;

	for bucle2 := 1 to tam_letras do
	begin
		if palabra [bucle1] = letras [bucle2].letra then
		begin
			letras[bucle2].cantidad := letras[bucle2].cantidad + 1;
			break;
		end //if palabra

		else
			no_repetidas := no_repetidas + 1;
	end; //bucle2

	if no_repetidas = tam_letras then
	begin
		tam_letras := tam_letras + 1;
		letras [tam_letras].letra := palabra[bucle1];
		letras [tam_letras].cantidad:= 1;
	end; //if no_repetidas
end; //bucle1

//Ordenación por número de repeticiones (de mayor a menor)
for bucle1 := 2 to longitud do
begin
	for bucle2 := 1 to (bucle1 - 1) do
	begin
		if letras[bucle1].cantidad > letras[bucle2].cantidad then
		begin
			auxiliar.letra := letras [bucle1].letra; auxiliar.cantidad := letras [bucle1].cantidad;
			letras[bucle1].letra := letras [bucle2].letra; letras[bucle1].cantidad := letras [bucle2].cantidad;
			letras[bucle2].letra := auxiliar.letra; letras[bucle2].cantidad := auxiliar.cantidad;
		end; //if
	end; //bucle2
end; //bucle1

//Presentación del resultado
	for bucle1 := 1 to tam_letras do
	begin
		if letras [bucle1].letra = ' ' then
			writeln ('Espacios: ', letras[bucle1].cantidad)
		else
			writeln (letras[bucle1].letra, ': ', letras[bucle1].cantidad);
	end; //bucle1

end.




05-Apr-2012 20:30
Luis Torres (+18)

Ahora sí funciona perfectamente. Muchas gracias por el código. Ahora le daré utilidad en otro programa. Muchos saludos.


05-Apr-2012 20:31
Luis Torres (+18)

Gracias por la respuesta, Fulanito de Tal. Voy a revisarlo. Saludos.


06-Apr-2012 19:33
Nacho Cabanes (+84)

Se puede hacer de una forma mucho más rápida, usando un array de 256 posiciones: cada letra tiene asociado un código numérico del 0 al 255 (el código ASCII), de modo que basta con preparar un array de ese tamaño e ir guardando en cada posición la cantidad veces que se ha encontrado la correspondiente letra hasta el momento.

El código ASCII de una letra se obtiene con la función "ord", y la letra se puede obtener a partir de su código ASCII con la función "chr", así:


program contarLetras;

var
  palabra: string;
  codigoLetra: byte;
  contadorLetras: array[1..255] of byte;
  i: integer;
  

begin
  write('Escribe una palabra o frase: ');
  readln(palabra);
  
  { valores iniciales a cero }
  for i := 1 to 255 do  
    contadorLetras[i] := 0;
    
  { recorro la cadena y aumento cada contador }
  for i := 1 to length(palabra) do  
  begin
    codigoLetra := ord( palabra[i] );
    inc( contadorLetras[codigoLetra] );
  end;
  
  { finalmente, muestro contadores }
  for i := 33 to 255 do 
    if contadorLetras[i] > 0 then
      writeln( chr(i),': ', contadorLetras[i]);
end.


 


06-Apr-2012 22:24
Sam Garcia

Excelentes aportes de Fulanito de Tal y por supuesto el profe Nacho.
Que bien que podamos de esta manera compartir nuestras ideas, en mi caso estoy aprendiendo bastante con los problemas y soluciones de este foro.

Saludos a todos.


07-Apr-2012 05:07
Luis Torres (+18)

Muy ingeniosa la respuesta del profesor Nacho Cabanes. Gracias a todos por haber sido tan amables en contestar con tan acertadas respuestas.
Saludos.


19-Oct-2014 03:30
Invitado (kate)

como podria ser el diagrama de flujo del anterior pseudocodigo


19-Oct-2014 14:17
Nacho Cabanes (+84)

La notación estándar de diagramas de flujo no permite expresar de forma clara la orden "for", sino que se indica con una condición con un salto atrás, como si se tratase de un "while", y con un contador que se incrementa justo antes del salto. A partir de esas pistas, no te debería costar implementar el diagrama completo...






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)