Ir al contenido



Foto

[MULTILENGUAJE] Contar las PALABRAS contenidas en un String


  • Por favor identifícate para responder
29 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.404 mensajes
  • LocationRepública Dominicana

Escrito 23 agosto 2010 - 12:29

Pues eso, con esta función podemos contar la cantidad de palabras que existe en un string separado entre espacio:


delphi
  1. function CuentaPalabras( s : string )
  2.   : integer;
  3. var
  4.   ps      : PChar;
  5.   nSpaces,
  6.   n        : integer;
  7. begin
  8.   n  := 0;
  9.   s  := s + #0;
  10.   ps := @s[ 1 ];
  11.   while ( #0 <> ps^ ) do
  12.   begin
  13.     while (' ' = ps^)and(#0 <> ps^) do
  14.     begin
  15.       inc( ps );
  16.     end;
  17.  
  18.     nSpaces := 0;
  19.     while (' ' <> ps^)and(#0 <> ps^) do
  20.     begin
  21.       inc( nSpaces );
  22.       inc( ps );
  23.     end;
  24.     if ( nSpaces > 0 ) then
  25.     begin
  26.       inc( n );
  27.     end;
  28.   end;
  29.   Result := n;
  30. end;


Saludos.
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.949 mensajes
  • LocationMéxico

Escrito 23 agosto 2010 - 12:50

Hey amigo, llevas 3 al hilo (y)

Salud OS
  • 0

#3 Caral

Caral

    Advanced Member

  • Administrador
  • 4.241 mensajes
  • LocationCosta Rica

Escrito 23 agosto 2010 - 02:02

Hola
Es que esta sacando el repertorio del baúl... *-) (y) (b)
Saludos
  • 0

#4 Master23

Master23

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 230 mensajes
  • LocationSanto Domingo

Escrito 23 agosto 2010 - 04:42

No se puede mostrar viendo length de el string simplemente ?
  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.252 mensajes
  • LocationArgentina

Escrito 23 agosto 2010 - 04:47

No se puede mostrar viendo length de el string simplemente ?

Pues me temo que no Master23. Length solamente regresa la longitud del string, y aquí lo que se busca es contar las palabras que éste tenga. Esto requiere más que un simple length.

Saludos,
  • 0

#6 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 23 agosto 2010 - 04:50

No se puede mostrar viendo length de el string simplemente ?


No amigo, porque el length te muestra el total de caracteres contenido en un String, no el total de palabras ;)

Saludox ! :)
  • 0

#7 Khronos

Khronos

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 56 mensajes

Escrito 23 agosto 2010 - 04:53

Hola enecumene, buena función, pero creo que se puede pulir un poco más:


delphi
  1. function CuentaPalabras(S: string): Cardinal;
  2. var
  3. i: integer;
  4. begin
  5.   result:= 0;
  6.     S:= Trim(S);
  7.     for i := 0 to Length(S) - 1 do
  8.         if (S[i] = ' ') and (S[i + 1] <> ' ') then
  9.           Inc(Result);
  10.     If Length(S) > 0 then Inc(Result);
  11. end;


Saludos.
  • 0

#8 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.404 mensajes
  • LocationRepública Dominicana

Escrito 24 agosto 2010 - 08:44

Excelente amigo Khronos, menos líneas mejor :D (b)
  • 0

#9 lezamablr

lezamablr

    Member

  • Miembros
  • PipPip
  • 25 mensajes

Escrito 03 septiembre 2010 - 04:32

O tambien:


delphi
  1. var
  2.   cuenta : TStringList;
  3. begin
  4.  
  5.   cuenta := TStringList.Create;
  6.  
  7.   cuenta.Delimiter := ' ';
  8.   cuenta.DelimitedText := 'Texto del cual se van a contar las palabras';
  9.  
  10.   ShowMessage(IntToStr(cuenta.Count));
  11.  
  12.   cuenta.Free;
  13. end;

 
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.949 mensajes
  • LocationMéxico

Escrito 03 septiembre 2010 - 04:53

Hola lezamablr

Simple, ingenioso y efectivo (y)

Salud OS
  • 0

#11 Jagluiperd

Jagluiperd

    Member

  • Miembros
  • PipPip
  • 36 mensajes
  • LocationBuscando a Wally

Escrito 03 septiembre 2010 - 09:04

Muy, muy bueno.

Funciona incluso con la siguiente cadena:


delphi
  1.     cuenta.DelimitedText := 'Texto  del  cual se  van a contar las palabras  ';


Solo falla si encuentra algún caracter que no conforma una palabra, como por ejemplo con la siguiente cadena:

delphi
  1.   cuenta.DelimitedText := 'Texto  del  . , ? cual se  van a contar las palabras  ';


Ya que cuenta esos ". , ?" como si fuesen una palaba cada uno.

De ello desprendo la simple lógica del proceso:
1- Cualquier cosa al principio y al final de una cadena que no sea un SPACE, es una palabra ->Sumo.
2- Cualquier cosa que esté entre 2 SPACE, que no sea un SPACE, y que no esté al principio
    o al final de una cadena, es una palabra->Sumo.

Podría mejorarse, pero aún así es elegante, simple y efectiva.

Gracias por el aporte.

(Probado en Lazarus 0.9.28.2/WXP_SP3)

Saludos.
  • 0

#12 bigleaguer

bigleaguer

    Advanced Member

  • Miembros
  • PipPipPip
  • 66 mensajes

Escrito 03 septiembre 2010 - 11:28

A petición de Jagluiperd, podemos mejorar un poco más el método para que solo cuente las palabras con letras ó que contengan un símbolo ó número seguido de una letra, Por ejm: ¿Hola?.
NOTA: El código está escrito en Delphi 2010.


delphi
  1. function CantidadPalabras(const AValor: string): Integer;
  2. const
  3.   CharSet: TSysCharSet = ['A'..'Z', 'Á'..'Ú', 'Ñ'];
  4. var
  5.   Cadena: TStringList;
  6.   Str: string;
  7.   Total: Integer;
  8. begin
  9.   Total  := 0;
  10.   Cadena := TStringList.Create;
  11.   try
  12.     Cadena.DelimitedText := AnsiUpperCase(Trim(AValor));
  13.  
  14.     { Recorremos cada palabra }
  15.     for Str in Cadena do
  16.       if CharInSet(Str[1], CharSet) then
  17.         Inc(Total)
  18.       else if (Length(Str) > 1) and (CharInSet(Str[2], CharSet)) then
  19.         Inc(Total);
  20.  
  21.     Result := Total;
  22.   finally
  23.     Cadena.Free;
  24.   end;
  25. end;


Y su uso sería:

delphi
  1. var
  2. Cant: Integer;
  3. begin
  4.   Cant := CantidadPalabras('Texto  del  . , ? cual se  van a contar las palabras  ');
  5. // Cant. Palabras = 9
  6. end;


Espero ayude un poco...
  • 0

#13 Jagluiperd

Jagluiperd

    Member

  • Miembros
  • PipPip
  • 36 mensajes
  • LocationBuscando a Wally

Escrito 04 septiembre 2010 - 04:28


delphi
  1. // Cant. Palabras = 9


Premio.

Gracias y un saludo.
  • 0

#14 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.837 mensajes
  • LocationMadrid - España

Escrito 04 septiembre 2010 - 04:55

Propongo esta variante usando la API IsCharAlpha.



delphi
  1. function ContarPalabras(const S: string): integer;
  2. var
  3.   i, L: integer;
  4. begin
  5.   L:= Length(S);
  6.   Result:= 0;
  7.   for i:= 1 to L do
  8.     if IsCharAlpha(S[i]) and (S[i-1] = ' ') then inc(Result);
  9.   if (L>0) and IsCharAlpha(S[L]) then inc(Result);
  10. end;


Saludos.
  • 0

#15 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.837 mensajes
  • LocationMadrid - España

Escrito 04 septiembre 2010 - 05:15

Y con esta otra versión, si me perdonáis el uso de punteros, mi propuesta para C/C++



cpp
  1. int ContarPalabras(char* S)
  2. {
  3.   int Result = 0;
  4.   int L = lstrlen(S);
  5.   for(char *c = S; *c;)
  6.     if(IsCharAlpha(*c++) && *c == ' ') Result++;
  7.   if (L>0 && IsCharAlpha(*(S+L-1))) Result++;
  8.   return Result;
  9. }


Saludos.
  • 0

#16 Jagluiperd

Jagluiperd

    Member

  • Miembros
  • PipPip
  • 36 mensajes
  • LocationBuscando a Wally

Escrito 04 septiembre 2010 - 06:22

Hola escafandra.

El código que propones no funciona al 100%.

Ejemplos de testeo:


delphi
  1. ContarPalabras('Texto '); {Devuelve 0 Palabras}
  2. ContarPalabras('Texto'); {Devuelve 1 Palabra}
  3. ContarPalabras('Texto  del  . , ? cual se  van a contar las palabras'); {Devuelve 9 Palabas}
  4. ContarPalabras('Texto  del  . , ? cual se  van a contar las palabras '); {Devuelve 8 Palabas}


Supongo que se deberá a la siguiente linea...

delphi
  1. if (L>0) and IsCharAlpha(S[L]) then inc(Result);

... Cuando la cadena finaliza con caracter SPACE.

Si me lo permites, he retocado un poco el código para que recoja y recupere ese error, y
además hacerlo independiente del S.O. y de la versión de este, al no depender de API alguna:


delphi
  1. {Añadir esta función tras la clausula Implementation}
  2. Function IsCharAlpha(Const Caracter: Char): Boolean;
  3. Begin
  4.   {No tiene en cuenta caráteres especiales, solo letras y números}
  5.   Result:=(Caracter IN['A'..'Z','a'..'z','0'..'9']);
  6. End;
  7.  
  8. {...}
  9. function ContarPalabras(const S: string): integer;
  10. var
  11.   i, L: integer;
  12. begin
  13.   L:= Length(S);
  14.   While Not(IsCharAlpha(S[L])) do
  15.     Begin
  16.       dec(L);
  17.     end;
  18.   Result:= 0;
  19.   for i:= 1 to L do
  20.     Begin;
  21.       if IsCharAlpha(S[i]) and (S[i-1] = ' ') then inc(Result);
  22.     end;
  23.   if (L>0) and IsCharAlpha(S[L]) then inc(Result);
  24.  
  25. end; 
  26.  
  27. {Ejemplos de testeo:
  28. ShowMessage(IntToStr(ContarPalabras('Texto  del  . , ? cual se  van a contar las palabras. ? ')));
  29. ShowMessage(IntToStr(ContarPalabras('Texto  del  . , ? cual se  van a contar las palabras')));
  30. }


Saludos.
  • 0

#17 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.837 mensajes
  • LocationMadrid - España

Escrito 04 septiembre 2010 - 06:42

oops  :(  Cierto.

La función que propuse en C/C++ no tiene ese bug, por algo es mi lenguaje favorito :D :D :D.

Bueno, el problema se corrige mejor y mas simple de esta manera:


delphi
  1. function ContarPalabras(const S: string): integer;
  2. var
  3.   i, L: integer;
  4. begin
  5.   L:= Length(S);
  6.   Result:= 0;
  7.   for i:= 0 to L-1 do
  8.     if IsCharAlpha(S) and (S[i+1] = ' ') then inc(Result);
  9.   if (L>0) and IsCharAlpha(S[L]) then inc(Result);
  10. end;

Aunque todavía podemos preguntarnos una cosa. ¿Los caracteres numéricos cuentan? si es así debemos cambiar la API IsCharAlpha por IsCharAlphaNumeric
 


delphi
  1. function ContarPalabras_(const S: string): integer;
  2. var
  3.   i, L: integer;
  4. begin
  5.   L:= Length(S);
  6.   Result:= 0;
  7.   for i:= 0 to L-1 do
  8.     if IsCharAlphaNumeric(S[i]) and (S[i+1] = ' ') then inc(Result);
  9.   if (L>0) and IsCharAlphaNumeric(S[L]) then inc(Result);
  10. end;

Saludos.


  • 0

#18 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.949 mensajes
  • LocationMéxico

Escrito 04 septiembre 2010 - 06:46

Todos los días me recuerdan que debo aprender C++ :)

Salud OS
  • 0

#19 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.837 mensajes
  • LocationMadrid - España

Escrito 04 septiembre 2010 - 06:54

Todos los días me recuerdan que debo aprender C++ :)

Salud OS


Amigo, el C/C++ es la base de la ciencia... :p. Es broma.

A pesar de su sintaxis, a mi me resulta mucho mas cómodo en tareas de bajo nivel y punteros. Creo que su sintaxis en esto ayuda mucho, al menos para mi es muy clara.

Aunque he de decir que mi experiencia escribiendo en delphi es limitada...  :(


Saludos.
  • 0

#20 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.949 mensajes
  • LocationMéxico

Escrito 04 septiembre 2010 - 07:00


Todos los días me recuerdan que debo aprender C++ :)

Salud OS


Amigo, el C/C++ es la base de la ciencia... :p. Es broma.

A pesar de su sintaxis, a mi me resulta mucho mas cómodo en tareas de bajo nivel y punteros. Creo que su sintaxis en esto ayuda mucho, al menos para mi es muy clara.

Aunque he de decir que mi experiencia escribiendo en delphi es limitada...  :(


Saludos.


A eso me refiero, he hecho algunas cosas con java, con C#, cosas no complejas, pero la forma como utilizan los recursos de C me parece genial, la verdad es que aprendo mucho de todos ya sea C, RIA, SQL, etc... el punto es que la mayoría de las veces me cuesta trabajo entender el código :)

Salud OS
  • 0