Imprimir la palabra mas larga de un string C++

Iniciado por MellaSystems, 15 Febrero 2015, 23:08 PM

0 Miembros y 1 Visitante están viendo este tema.

MellaSystems

Gente necesito una ayudita... Quiero hacer una funcion que reciba un string y que dentro del string busque la palabra mas larga y la imprima. Y quisiera saber como voltear un string alreves pero que se quede en la misma posicion con los metodos sort() y reverse().

tengo esto asi las pude voltear:

#include <iostream>
#include <string>
using namespace std;

void invertStringWords(string);
void countVocals(string);
void countConsonants(string);
void countSpecialCharacters(string);
void displayMaxCharacterWords(string);
void countWords(string);

int main() {
    string words;
    std::cout<<"Introduzca alguna frase: ";
    std::getline(std::cin,words);
   
    cout << endl << "Sentencia original: \t" << words << endl;
    reverse(words.begin(),words.end());
    invertStringWords(words);
   
   
    system("pause");
    return 0;
}

//Funcion que invierte el orden de las palabras en una cadena
void invertStringWords(string words) {
          //Arreglo con la longitud de los caracteres en la sentencia
          int arraylength = words.length();

          // índice para el caracter que está siendo leído
          int a=0;

          // String para almacenar la última palabra formada del arreglo
          string invert="";

          // Arreglo de caracteres con la cadena final de palabras invertidas
           char invertedWords[arraylength];

           // Ciclo que recorre la cadena original desde el final
           for(int i=arraylength-1; i >= -1; i--){
             // Si encontramos un espacio ya hemos terminado una palabra
             // invertir la palabra y agregarla al principio del arreglo invertido
             if(i==-1 || words == ' ') {
                         // Agregar la última palabra encontrada invertida en la sentencia
                         // al principio del arreglo de cadena invertida
                         for(int b=invert.length()-1; b >=0 ; b--) {
                                 invertedWords[a] = invert;
                                 a++;
                         }
                         // Agregar un espacio para delimitar palabra e incrementar el contador
                         // 'a' solo si no se ha llegado al final del arreglo.
                         if (i>-1)
                            invertedWords[a++] = ' ';
                         invert="";
             }
             else
             {
              // Tenemos un caracter, agregarlo a la cadena temporal
                         invert +=words;
             }
     }
             cout << endl << "Sentencia invertida: \t" << invertedWords << endl;
}

Miseryk

#1
Cita de: MellaSystems en 15 Febrero 2015, 23:08 PM
Gente necesito una ayudita... Quiero hacer una funcion que reciba un string y que dentro del string busque la palabra mas larga y la imprima. Y quisiera saber como voltear un string alreves pero que se quede en la misma posicion con los metodos sort() y reverse().

tengo esto asi las pude voltear:

#include <iostream>
#include <string>
using namespace std;

void invertStringWords(string);
void countVocals(string);
void countConsonants(string);
void countSpecialCharacters(string);
void displayMaxCharacterWords(string);
void countWords(string);

int main() {
   string words;
   std::cout<<"Introduzca alguna frase: ";
   std::getline(std::cin,words);
   
   cout << endl << "Sentencia original: \t" << words << endl;
   reverse(words.begin(),words.end());
   invertStringWords(words);
   
   
   system("pause");
   return 0;
}

//Funcion que invierte el orden de las palabras en una cadena
void invertStringWords(string words) {
         //Arreglo con la longitud de los caracteres en la sentencia
         int arraylength = words.length();

         // índice para el caracter que está siendo leído
         int a=0;

         // String para almacenar la última palabra formada del arreglo
         string invert="";

         // Arreglo de caracteres con la cadena final de palabras invertidas
          char invertedWords[arraylength];

          // Ciclo que recorre la cadena original desde el final
          for(int i=arraylength-1; i >= -1; i--){
            // Si encontramos un espacio ya hemos terminado una palabra
            // invertir la palabra y agregarla al principio del arreglo invertido
            if(i==-1 || words == ' ') {
                        // Agregar la última palabra encontrada invertida en la sentencia
                        // al principio del arreglo de cadena invertida
                        for(int b=invert.length()-1; b >=0 ; b--) {
                                invertedWords[a] = invert;
                                a++;
                        }
                        // Agregar un espacio para delimitar palabra e incrementar el contador
                        // 'a' solo si no se ha llegado al final del arreglo.
                        if (i>-1)
                           invertedWords[a++] = ' ';
                        invert="";
            }
            else
            {
             // Tenemos un caracter, agregarlo a la cadena temporal
                        invert +=words;
            }
    }
            cout << endl << "Sentencia invertida: \t" << invertedWords << endl;
}

Yo para obtener la frase más larga, lo que haría es rermplazar los "." (puntos), "," (comas) y demás con espacios, luego hago un split con delimitador de " " (espacio) y tengo todas las palabras separadas, busco en cada index cuál tiene la mayor longitud y guardo ese string y el index si es necesario.

Y para voltear un string lo que tenés que hacer es ir leyendo el address del string original desde su última posición hacia su principio e ir copiando cada byte a otro address de otro string.
Can you see it?
The worst is over
The monsters in my head are scared of love
Fallen people listen up! It's never too late to change our luck
So, don't let them steal your light
Don't let them break your stride
There is light on the other side
And you'll see all the raindrops falling behind
Make it out tonight
it's a revolution

CL!!!

Miseryk

Código (cpp) [Seleccionar]

#include <iostream>
#include <Windows.h>

using namespace std;

int main()
{
char Orig[] = {"1234567"};

int lenStr = strlen(Orig);

char * output = new char[lenStr + 1];

__asm
{
pushad

std
mov ecx, lenStr

lea esi, Orig
add esi, ecx
dec esi
mov edi, output
zrep:
movsb
inc edi
inc edi
loop zrep
mov byte ptr [edi], 0x00

popad
}

cout << output << endl; //7654321

delete[] output;

cin.get();

return 0;
}
Can you see it?
The worst is over
The monsters in my head are scared of love
Fallen people listen up! It's never too late to change our luck
So, don't let them steal your light
Don't let them break your stride
There is light on the other side
And you'll see all the raindrops falling behind
Make it out tonight
it's a revolution

CL!!!

eferion

Invertir un string... que tal así:

Código (cpp) [Seleccionar]

int main( )
{
  std::string cadena = "0123456789";
  std::string invertida( cadena.rbegin( ), cadena.rend( ) );

  std::cout << invertida << std::endl;
}


En cuanto a encontrar la palabra más larga... con iteradores se puede conseguir fácilmente:

Código (cpp) [Seleccionar]

void PalabraMasLarga( const std::string& cadena )
{
  std::string palabra;
  auto it = cadena.begin( );

  for( auto it2 = it; it2 != cadena.end( ); ++it2 )
  {
    if ( *it2 == ' ' )
    {
      size_t length = std::distance( it, it2 );
      if ( length > palabra.size( ) )
        palabra = std::string( it, it2 );
      it = it2+1;
    }
  }

  std::cout << palabra << std::endl;
}


El codigo usa dos iteradores, uno apunta al inicio de la palabra actual y el otro va avanzando hasta encontrar un espacio, si la longitud de la cadena es mayor que la palabra más larga encontrada hasta ahora, la sustituye.

Simple y rápido.

Miseryk

Cita de: eferion en 16 Febrero 2015, 11:26 AM
Invertir un string... que tal así:

Código (cpp) [Seleccionar]

int main( )
{
  std::string cadena = "0123456789";
  std::string invertida( cadena.rbegin( ), cadena.rend( ) );

  std::cout << invertida << std::endl;
}


En cuanto a encontrar la palabra más larga... con iteradores se puede conseguir fácilmente:

Código (cpp) [Seleccionar]

void PalabraMasLarga( const std::string& cadena )
{
  std::string palabra;
  auto it = cadena.begin( );

  for( auto it2 = it; it2 != cadena.end( ); ++it2 )
  {
    if ( *it2 == ' ' )
    {
      size_t length = std::distance( it, it2 );
      if ( length > palabra.size( ) )
        palabra = std::string( it, it2 );
      it = it2+1;
    }
  }

  std::cout << palabra << std::endl;
}


El codigo usa dos iteradores, uno apunta al inicio de la palabra actual y el otro va avanzando hasta encontrar un espacio, si la longitud de la cadena es mayor que la palabra más larga encontrada hasta ahora, la sustituye.

Simple y rápido.

Muy bueno el invertir cadena, con respecto a la PalabraMasLargar hay un bug.

Código (cpp) [Seleccionar]

PalabraMasLarga("Buscandox la palabra más larga, pero tal vez no funcione,. porque falta algo.");


Código (ini) [Seleccionar]

OutPut: "funcione,.", el cual tendría que ser "Buscandox"
Can you see it?
The worst is over
The monsters in my head are scared of love
Fallen people listen up! It's never too late to change our luck
So, don't let them steal your light
Don't let them break your stride
There is light on the other side
And you'll see all the raindrops falling behind
Make it out tonight
it's a revolution

CL!!!

eferion

Cita de: Miseryk en 16 Febrero 2015, 15:52 PM
Muy bueno el invertir cadena, con respecto a la PalabraMasLargar hay un bug.

La idea no era dar un código completo... si miras el algoritmo ves que separa palabras únicamente por espacios, pero se puede mejorar fácilmente para que sea capaz de reconocer otros tipos de separadores.

Código (cpp) [Seleccionar]
if ( *it2 == ' '  || *it2 == ',' || *it2 == '.' /* ... */ )


Miseryk

Cita de: eferion en 16 Febrero 2015, 16:20 PM
La idea no era dar un código completo... si miras el algoritmo ves que separa palabras únicamente por espacios, pero se puede mejorar fácilmente para que sea capaz de reconocer otros tipos de separadores.

Código (cpp) [Seleccionar]
if ( *it2 == ' '  || *it2 == ',' || *it2 == '.' /* ... */ )



Interesante, tengo que ponerme a ver el nuevo framework, me quedé en string, pero no conocía "auto", gracias.
Can you see it?
The worst is over
The monsters in my head are scared of love
Fallen people listen up! It's never too late to change our luck
So, don't let them steal your light
Don't let them break your stride
There is light on the other side
And you'll see all the raindrops falling behind
Make it out tonight
it's a revolution

CL!!!

MellaSystems

Muchas gracias a los dos por su aporte Myseryk y eferion muy buenos aportes

Skynet96