[ Foro de Pascal ]
¿Alguien me podría indicar la manera en la que puedo contar cada letra en una palabra?. Se los agradecería. Saludos.
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!
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.
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!
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.
Ahora sí funciona perfectamente. Muchas gracias por el código. Ahora le daré utilidad en otro programa. Muchos saludos.
Gracias por la respuesta, Fulanito de Tal. Voy a revisarlo. Saludos.
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.
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.
Muy ingeniosa la respuesta del profesor Nacho Cabanes. Gracias a todos por haber sido tan amables en contestar con tan acertadas respuestas.
Saludos.
como podria ser el diagrama de flujo del anterior pseudocodigo
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.)