[ Foro de Pascal ]

Eliminar blancos extras en una cadena.

23-Apr-2012 18:21
Luis Torres (+18)
9 Respuestas

  Un gran saludos a todos lo miembros de este foro. Tengo un problema que aún no he podido resolver. Se trata de que me dan una cadena en la que aparecen palabras separadas por más de un espacio en blanco.  El propósito del programa que tengo que hacer es el de eliminar esos espacios extras y que la cadena finalmente quede conformada por palabras separadas por un solo espacio en blanco. Como ejemplo pongo lo siguiente:

Cadena de Entada:
   'Esta es  una    cadena    de     prueba.'

Cadena de Salida:
   'Esta es una cadena de prueba.'


  Les agradecería cualquier orientación que me pudieran dar. Lo he intentado varias veces pero aún no encuentro la solución correcta.


23-Apr-2012 22:22
Sam Garcia

Que tal!

Para darle solucion a lo que estas planteando se me ocurria lo sigueinte:

Un ciclo que recorra la cadena y verifique que no esten 2 espacios en blanco juntos, esto con la ayuda de una bandera, y el resultado ya depurado lo vaya almacenando en otra cadena auxiliar, algo asi:

...

function depuraEspacios(cadena:string): string;
var
 x:integer;
 aux: string;
 HayEspacio:boolean;
begin
 aux='';
 HayEspacio:=false;
 for x=1 to length(cadena) do
 begin
   if (cadena[x]=' ') then
   begin
     if not HayEspacio then
     begin
       aux:=aux+cadena[x]
       HayEspacio:=true;
     end;
   end;
   else
   begin
     aux:=aux+cadena[x];
     if HayEspacio then
       HayEspacio:=false;
   end;
 end;
 depurarEspacios:=aux;
end;

...

Espero pueda ayudarte..

Saludos!


23-Apr-2012 23:50
Luis Torres (+18)

Gracias, Sam Garcia, funcionó bien.
Ahora me gustaría preguntarte si es posible extraer de la cadena cada palabra por separado. Es que necesito hacer un ejercicio tomando cada palabra de una cadena.
Muchos Saludos.


24-Apr-2012 04:34
Sam Garcia

Que tal Luis, de nada, que bien que te funciono.

Respecto a tu pregunta de extraer cada palabra, de seguro que si se puede. Lo que se me ocurre es recorrer la cadena con un ciclo y cada espacio en blanco es nuestra señal de cambio de palabra. Ahora bien seria de adaptarlo dependiendo que quieras hacer con esas palabras, si imprimirlas en pantalla -creo que seria lo mas facial XD - o llevarlas a un archivo, o talvez almacenarlas temporalmente en un puntero de strings, puesto que asi como puede haber una palabra, puede que nos encontremos con 20, la cantidad no es fija.

Esperemos para ver la opinion del profe Nacho.

Saludos!


25-Apr-2012 00:45
Luis Torres (+18)

Gracias por tu respueta, Sam. Trataré de hacerlo a ver si me sale. Muchos saludos.


25-Apr-2012 09:45
Nacho Cabanes (+83)

Como comenta Sam, la forma de hacerlo es usar los espacios (que ahora ya son únicos) para saber dónde termina cada palabra.

El qué hacer a partir de entonces... depende de lo que te pidan. Por ejemplo, si es simplemente mostrar cada palabra en una línea, ya es casi trivial: tomas cada letra y la escribes (Write); cuando encuentres un espacio, avanzas de línea (WriteLn).

Si tienes que memorizar todas las palabras para hacer alguna operación con ellas, como en este ejercicio, que las escribe en orden inverso:

http://www.nachocabanes.com/retos/reto.php?n=002

o este otro, que suma varios números:

http://www.nachocabanes.com/retos/reto.php?n=001

La situación se complica, porque no sabes a priori cuantas palabras hay, así que tienes tres alternativas (en Pascal):

- Crear un array sobradamente grande, para que quepan todas las palabras que esperas poder encontrar.

- Usar una estructura dinámica, para que el tamaño sea totalmente variable (una cola si vas a tomar los datos en orden, una pila si los tomas al revés, o una lista general si vas a acceder a elementos sueltos).

- Si la versión de Pascal que usas permite crear arrays desde dentro de una función, y no sólo en la sección "var", puedes dar una primera pasada para contar los espacios, y entonces sabrás cuantas palabras tienes (si hay 3 espacios intermedios, tienes 4 palabras), de modo que podrías crear un un array del tamaño exacto que necesitas, y guardar los datos en él en una segunda pasada.


26-Apr-2012 11:57
Fulanito de Tal

Este programita sirve para eliminar los espacios en blanco que puede haber delante de la cadena, al final de la misma, y también para eliminar dobles espacios entre palabras.
También extrae palabra por palabra utilizando el algoritmo expuesto por Nacho Cabanes.

var
posicion: byte;
cadena: string;

begin
write ('Teclea una frase: ');
readln (cadena);

//eliminamos espacios al principio
while cadena[1] = ' ' do
begin
delete (cadena, 1, 1);
end;

//eliminamos espacios al final
while cadena [length (cadena)] = ' ' do
begin
delete (cadena, length(cadena), 1);
end;

//eliminamos espacios dobles entre palabras
posicion:= 0;

while posicion < length (cadena) do
begin

posicion:= posicion + 1;

if (cadena[posicion] = ' ') and (cadena[posicion + 1] = ' ') then
begin
delete (cadena, posicion, 1);
posicion:= posicion - 1;
end;

end;

writeln;

//escribimos la frase sin espacios de más
writeln ('La frase sin espacios de más:');
writeln (cadena);

writeln;

//seleccionar palabra por palabra
posicion := 0;

writeln ('Las palabras de la frase:');

while posicion < length (cadena) do
begin

posicion := posicion + 1;

if cadena[posicion] <> ' ' then
write (cadena [posicion])
else
writeln;
end;

end.


27-Apr-2012 03:56
Luis Torres (+18)

Mil gracias a todos por sus respuestas: a Sam, Fulanito de Tal y por supuesto al prof. Nacho. ¡Qué amables son en responderme!!!, ahora todo lo tengo mucho más claro y, sólo me falta muy poco para terminar el ejercicio. Saludos.


04-May-2012 23:01
Nacho Cabanes (+83)

¡Magia!  Ya se pueden publicar los fuentes "bonitos", con la sintaxis en colores. Por ejemplo, el fuente anterior de "fulanito de tal" podría quedar así:


var
    posicion: byte;
    cadena: string;

begin
    write ('Teclea una frase: ');
    readln (cadena);

    //eliminamos espacios al principio
    while cadena[1] = ' ' do
        begin
        delete (cadena, 1, 1);
        end;

    //eliminamos espacios al final
    while cadena [length (cadena)] = ' ' do
        begin
        delete (cadena, length(cadena), 1);
        end;

    //eliminamos espacios dobles entre palabras
    posicion:= 0;

    while posicion < length (cadena) do
        begin

        posicion:= posicion + 1;

        if (cadena[posicion] = ' ') and (cadena[posicion + 1] = ' ') then
            begin
            delete (cadena, posicion, 1);
            posicion:= posicion - 1;
            end;

        end;

    writeln;

    //escribimos la frase sin espacios de más
    writeln ('La frase sin espacios de más:');
    writeln (cadena);

    writeln;

    //seleccionar palabra por palabra
    posicion := 0;

    writeln ('Las palabras de la frase:');

    while posicion < length (cadena) do
        begin

        posicion := posicion + 1;

        if cadena[posicion] <> ' ' then
            write (cadena [posicion])
        else
            writeln;
        end;

end.


05-May-2012 01:52
Luis Torres (+18)

¡Qué bien!!!. Hacía falta tener esa facilidad. Me alegra, además, que el primer código publicado con este estilo sea el de un ejercicio que yo pregunté y, Fulanito, Sam y Nacho Cabanes respondieron amablemente. Saludos.






(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.)