[ Foro de Pascal ]
Hola profesor y compañero luis, queria pedir su ayuda en como puedo validar que el primer caracter de la palabra se repite una sola vez en una palabra ingresada por teclado, mil gracias.
hola podrian ayudarme con la validacion, mil gracias
Se me había pasado esta pregunta.
Por partes:
- Validar algo que introduzca el usuario se hará típicamente con un "read..until".
- El primer carácter de una frase lo puedes obtener con "frase[1]".
- Para compararlo con todas las demás, puedes usar un "for" que recorra desde la posición 2 hasta la última (length) de la frase.
- Para memorizar si lo has encontrado repetido o no, puedes ayudarte de una variable booleana, o de un contador.
Prepara un esqueleto con esas ideas y ponlo aquí, para que podamos ver qué detalles te faltan.
hola profesor
mira estoy casi volviendome loco tratando de llevar tus ideas a la solucion de mi programa, pero tengo errores en ejecusion, por favor ayudame me rindo llevo horas. he intentado primero que todo validar que la cadena ingresada tenga una longitud mayor a 1, pues de lo contrario si le permito al usuario ,creo yo, que introduzca un caracter no tiene sentido el programa que se intenta. e intentado tambien realizarlo con un while por que creo que con un for no es muy eficiente, dado que si se encuentra antes de finalizar toda la longitud de la cadena un caracter repetido respecto al primero de la cadena, el for sigue ejecutandose, bien asi y todo no me sale, porejemplo si lo ejecutas en casos como porejemplo:
ingrese una cadena:
zz
vuelva a ingresar una caracter cuyo primer caracter no se repita:
ingrese una cadena:
ramiro
vuelva a ingresar una caracter cuyo primer caracter no se repita:
ingrese una cadena:
mariom
vuelva a ingresar una caracter cuyo primer caracter no se repita:
ingrese una cadena:
mario // aqui vuelve y me pide una cadena no se porque, pues aqui deberia mostrar:
cadena correctamente validada ! ?????
vuelva a ingresar una caracter cuyo primer caracter no se repita:
ingrese una cadena:
tambien mira este caso de ejecución por favor: en este caso ejecuta bien
ingrese una cadena:
z
ingrese una cadena de mayor longitud:
ingrese una cadena:
mario
cadena correctamente validada.
pero si es ahora algo como:
ingrese una cadena:
z
ingrese una cadena de mayor longitud:
ingrese una cadena:
ramiro
vuelva a ingresar una caracter cuyo primer caracter no se repita:
ingrese una cadena:
z //aqui se queda el programa
por favor corrigeme todos los errores que veas de logica y codificacion o lineas innecesarias y lo mas importante ayudame a corregir mi codigo para que me funcione cual deseo, te has dado cuenta que lo he trabajado y no me sale quiza tenga cuestiones no tan graves y sea una tonteria mis errores pero necesito que me lo hagas ver, ojala puedas corregirme y modificar mi programa para que funcione asi con todas estas horas que llevo intentandolo al ver tu solucion pueda ver en que estaba fallando y aprender de ello, mil gracias por tu atencion, ayuda y paciencia.
estos son mis codigos, primero esta haciendolo con el for, pero como te dije funciona hasta cierto punto, pues no valide lo de la longitud no permitida para cadenas de un caracter. y el segundo codigo es ya el final donde tuve todos los problemas que te mencione antes con ejemplos y esta hecho con while en vez de for intentando ser eficiente no se y con validacion de cadenas con un solo caracter
1
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
writeln('ingrese una cadena :');
readln(cadena);
repeat
encontrado:=false;
primC:=cadena[1];
for i:=2 to length(cadena) do
if cadena[i]=primC then
encontrado:=true;
if (encontrado = true) then {and (length(cadena)>1)}
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
writeln('cadena correctamente ingresada ');
end;
until (encontrado =false); {or (length(cadena)<=1)}
{if (encontrado = false) then
writeln('cadena correctamente validada ! ');}
readln;
end.
2.
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
begin
writeln('ingrese una cadena de mayor longitud :');
writeln('ingrese una cadena :');
readln(cadena);
end;
until length(cadena)>1;
repeat
encontrado:=false;
primC:=cadena[1];
i:=2;
while (cadena[i] <> primC) and (i<=length(cadena)) do
begin
i:=i+1;
end;
if (cadena[i]=primC) then
encontrado:=true;
if (encontrado = true) then
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
if (encontrado = false) and (length(cadena)>1) then
writeln('cadena correctamente validada ! ');
end;
until (encontrado =false);
readln;
end.
mil gracias, estoy agotado ojala me ayudes a solucionarlo y a corregir mis errores.
El primero de tus fuentes está muy cerca, aunque al final lo complicas... y lo estropeas... ;-D
Mira, partiendo de la base del tuyo se puede hacer esto:
program NoRepetirPrimera;
var
cadena: string;
i: integer;
existeDuplicado: boolean;
primeraLetra: char;
begin
repeat
writeLn('ingrese una cadena :');
readLn(cadena);
existeDuplicado := false;
primeraLetra := cadena[1];
for i := 2 to length(cadena) do
if cadena[i] = primeraLetra then
existeDuplicado:=true;
if existeDuplicado then
writeLn('Incorrecta: el primer caracter se repite');
until not existeDuplicado;
writeLn('cadena correctamente ingresada ');
end.
buen dia profesor.
gracias ante todo por responderme.
profesor ok el primero de los fuentes con el for ya vi porque falle, pero como te decia no seria ineficiente este fuente al usar el for, pues para que recorrer toda la cadena si quiza el primer repetido al primer caracter este antes de toda la longitud de la cadena? por eso intente hacerlo con mi forma de codigo 2., podrias ayudarme a entender o a modificar dicho codigo , teniendo en cuenta las validaciones como la que la cadena debe ser mayor de un caracter y que se lo pregunte al usuario, por favor reviza en ejecusion mi segundo codigo y dime en que fallo y que debo corregir, gracias nacho.
profesor porque dices que al final estropeo mi primer codigo, lo que ocurre es que me interesa que si se ingresa una cadena en la cual de repita el primer caracter que le de la posibilidad al usuario de introducir otra que sea correcta, y en tu codigo final modificado no haces esa opcion por eso yo intente hacer:
if (encontrado = true) then {and (length(cadena)>1)}
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
writeln('cadena correctamente ingresada ');
end;
segun tu codigo en que forma o en que parte de tu codigo deberia ir esa opcion para el usuario? me lo indicas en tu codigo por favor , gracias
Claro que mi código modificado permite esa nueva introducción de datos. Eso es lo que hace el "repeat..until". Pruébalo. ;-D
si es verdad profesor disculpa, pero si tienes razon tu codigo lo esta contemplando , quisiera por favor me corriegieras el formato del mismo programa pero sin el for sino con un while
que esta mal y que debo rectificar y si tengo razon en lo que te comentaba de la solucion con el for de ser un tanto ineficiente respecto que se esta recorriendo toda la longitud de la cadena en casos innecesarios como cuando el caracter repetido puede estar en una posicion mas cercana al primer caracter que al final, mil gracias profesor
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
begin
writeln('ingrese una cadena de mayor longitud :');
writeln('ingrese una cadena :');
readln(cadena);
end;
until length(cadena)>1;
repeat
encontrado:=false;
primC:=cadena[1];
i:=2;
while (cadena[i] <> primC) and (i<=length(cadena)) do
begin
i:=i+1;
end;
if (cadena[i]=primC) then
encontrado:=true;
if (encontrado = true) then
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
if (encontrado = false) and (length(cadena)>1) then
writeln('cadena correctamente validada ! ');
end;
until (encontrado =false);
readln;
end.
Efectivamente, un "while" termina el análisis en cuanto encuentra una coincidencia, con lo que, en general, será más rápido que un "for" en un problema como éste, y tu planteamiento parece correcto.
hola profesor nacho.
gracias por tu aclaracion del while, sin embargo te pido por favor ejecutes mi codigo para que me puedas indicar por favor a decirme en que estoy fallando,pues en el caso de ejemplo como:
ingrese una cadena:
zz
vuelva a ingresar una cadena cuyo primer caracter no se repita :
ingrese una cadena:
ramiro
vuelva a ingresar una cadena cuyo primer caracter no se repita :
ingrese una cadena:
z
ahi se me queda el programa cuando lo que deberia aparecerme en este ultimo ingreso es:
ingrese una cadena de mayor longitud :
ingrese una cadena :
...
por favor ayudame a ver donde esta mi error y que debo corregir que veas innecesario , muchas gracias por la ayuda que me prestes y por tu tiempo.
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
begin
writeln('ingrese una cadena de mayor longitud :');
writeln('ingrese una cadena :');
readln(cadena);
end;
until length(cadena)>1;
repeat
encontrado:=false;
primC:=cadena[1];
i:=2;
while (cadena[i] <> primC) and (i<=length(cadena)) do
begin
i:=i+1;
end;
if (cadena[i]=primC) then
encontrado:=true;
if (encontrado = true) then
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
if (encontrado = false) and (length(cadena)>1) then
writeln('cadena correctamente validada ! ');
end;
until (encontrado =false);
readln;
end.
Es que sigue habiendo código repetitivo. No debe haber 2 readLn, debes pedir sólo al principio de cada repetición.
program ValidarPrimerCaracterWhile;
var
cadena:string;
i:integer;
existeDuplicado:boolean;
primeraLetra:char;
begin
repeat
existeDuplicado := false;
writeLn('Ingrese una cadena: ');
readLn(cadena);
if length(cadena) <=1 then
writeLn('La longitud debe ser mayor que 1')
else
begin
primeraLetra := cadena[1];
i := 2;
while (cadena[i] <> primeraLetra) and (i<=length(cadena)) do
i := i+1;
if (cadena[i] = primeraLetra) then
begin
existeDuplicado := true;
writeLn('El primer caracter se repite');
end;
end;
until (not existeDuplicado) and (length(cadena) > 1);
writeLn('Cadena correctamente validada');
end.
hola profesor nacho, queria hacerte una pregunta mas sobre este ejercicio, es importante para mi aclarar lo siguiente y quien mejor que tu para dejarmelo claro :
profesor en la solucion con el for o (incluso con la del while )
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
begin
writeln('ingrese una cadena de mayor longitud :');
writeln('ingrese una cadena :');
readln(cadena);
end;
until length(cadena)>1;
repeat
encontrado:=false;
primC:=cadena[1];
i:=2;
while (cadena[i] <> primC) and (i<=length(cadena)) do
begin
i:=i+1;
end;
if (cadena[i]=primC) then
encontrado:=true;
if (encontrado = true) then
begin
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
writeln('ingrese una cadena :');
readln(cadena);
end
else
begin
if (encontrado = false) and (length(cadena)>1) then
writeln('cadena correctamente validada ! ');
end;
until (encontrado =false);
readln;
end.
seria innecesario en la condicion del until adicionar un and conlength(cadena)>1
es decir que la condicion del until quede:
...
until (encontrado =false) and (length(cadena)>1);
dado que estoy dentro del repeat validando:
if length(cadena) <=1 then
begin
writeln('ingrese una cadena de mayor longitud :');
writeln('ingrese una cadena :');
readln(cadena);
...
he probado como te lo puse y funciona perfecto pero me queda esa gran duda de si debo completar con el and la otra parte del until o si no es necesario y me des por favor un buen si o un buen no para tenerlo encuenta en problemas algo parecidos al respecto...mil gracias
Verás que mi solución es distinta, más compacta (cerca de las dos terceras partes del tamaño de la tuya) y usa un único "readLn".
Tu solución tiene dos "readLn", y cada bloque valida cosas distintas, lo que es muy peligroso: Si la primera palabra que introduces es "salsa", la longitud es correcta, pero no es válido el hecho de que repita la primera letra. Después hay un segundo "readLn", y ese te permitirá introducir palabras de una única letra si eliminas esa condición del "until".
Si no simplificas tu solución, será peligroso eliminar condiciones, porque puedes permitir que haya efectos colaterales.
ah ok , profesor ahora lo entiendo perfectamente te dejo mi codigo pero mi pregunta ahora que lo he modificado supongo correctamente, ya me lo diras, queria preguntarte si es necesario la parte del and en la que hago referencia a: and (length(cadena) > 1); en:
until (encontrado =false) and (length(cadena) > 1);
te lo pregunto por que si quito esta parte y la dejo como
until (encontrado =false) ; me funciona de igual manera correctamente, agradezco tu aclaracion a mi duda
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
writeLn('La longitud debe ser mayor que 1')
else
begin
encontrado:=false;
primC:=cadena[1];
for i:=2 to length(cadena) do
if cadena[i]=primC then
encontrado:=true;
if (encontrado = true) then
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
end;
until (encontrado =false) and (length(cadena) > 1);
if (encontrado = false) then
writeln('cadena correctamente validada ! ');
readln;
end.
Si eliminas el "and (length(cadena) > 1);", eliminas uno de los dos motivos de repetición. Dejará de volver a pedirte la frase cuando la longitud sea 1, de modo que el comportamiento no será el que tú esperabas.
hola profesor, me queda super claro lo del "and (length(cadena) > 1);"
queria preguntarte y disculpame es que me surgen una vez resuelvo una duda otra y en este caso quisiera preguntarte por el:
encontrado:=false;
tal como lo tengo ubicado ( y teniendo el until completo es decir:
until (encontrado =false) and (length(cadena) > 1); ), porque si en ejecucion ingreso de entrada una cadena de longitud uno se sale del repeat, acaso por defecto el until siempre lo toma pascal como true??
y si lo correcto seria entonces sacar el encontrado;= false; del else del if y ponerlo despues del repeat como te lo indico en este codigo: ????
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
encontrado:=false;
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
writeLn('La longitud debe ser mayor que 1')
else
begin
primC:=cadena[1];
for i:=2 to length(cadena) do
if cadena[i]=primC then
encontrado:=true;
if (encontrado = true) then
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
end;
until (encontrado =false) and (length(cadena) > 1);
if (encontrado = false) then
writeln('cadena correctamente validada ! ');
readln;
end.
gracias inmensas profesor por tu aclaracion a mis dudas .
Si escribes
until (encontrado =false) and (length(cadena) > 1);
y la longitud de la cadena es mayor que uno, no se sale del "repeat-until"; porque hay DOS CONDICIONES, unidas por un AND, de modo que deben cumplirse ambas a la vez. Si no se cumple la condición "encontrado=false" (fíjate que yo la he llamado "existeDuplicado", que resulta más legible), no se sale del "repeat", porque parte de la condición no se cumple.
hola profesor, osea que segun tu explicacion estoy en lo correcto cuando te digo que lo correcto seria entonces sacar el encontrado;= false; del else del if y ponerlo despues del repeat como te lo indico en este codigo: solo dime si si o no por favor
program validarprimercaracter;
uses crt;
var cadena:string;
i:integer;
encontrado:boolean;
primC:char;
begin
clrscr;
repeat
encontrado:=false;
writeln('ingrese una cadena :');
readln(cadena);
if length(cadena) <=1 then
writeLn('La longitud debe ser mayor que 1')
else
begin
primC:=cadena[1];
for i:=2 to length(cadena) do
if cadena[i]=primC then
encontrado:=true;
if (encontrado = true) then
writeln(' vuelva a ingresar una cadena cuyo primer caracter no se repita : ');
end;
until (encontrado =false) and (length(cadena) > 1);
if (encontrado = false) then
writeln('cadena correctamente validada ! ');
readln;
end.
gracias
La diferencia no es importante.
Esta última solución, en la que prefijas el valor de "encontrado" nada más empezar, puede resultar más legible, pero el funcionamiento real va a ser idéntico, por lo que te comentaba: antes sólo le dabas valor si la longitud es mayor que uno; ahora le das valor siempre, pero ese valor no será importante a no ser que la longitud sea mayor que uno (porque han de verificarse las dos condiciones).
hola profesor, haber lo que quiero que me digas es si esta bien o esta mal, eso si agradeciendo el tiempo que te tomas para que pueda entender las diferencias.gracias
(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.)