Fácil-medio · cadenas

Invertir el orden de las palabras

cin >> x lee una palabra y se detiene en el primer espacio. Las frases necesitan otra herramienta; y con la línea completa, separar palabras es solo un bucle con dos índices.

En una fraseLee la línea con <code>cin.getline</code>, córtala por los espacios y escribe las palabras de la última a la primera, separadas por un solo espacio.

El problema

Entrada: Una línea de texto: de 1 a 100 palabras separadas por uno o más espacios. Las palabras no contienen espacios; la línea mide como mucho 200 caracteres.

Salida: Las mismas palabras en orden inverso, separadas por un solo espacio, y un salto de línea al final.

Ejemplos:

EntradaSalida
the quick brown foxfox brown quick the
hellohello
a b cc b a

Lo que se invierte es el orden de las palabras: dentro de cada una las letras no cambian — inviertes la secuencia de palabras, no los caracteres (eso era Invertir una cadena).

Tu solución

main.cpp — tu solución
Entrada personalizada para «Ejecutar mi entrada»

La corrección corre en tu navegador contra pruebas ocultas. Un bucle infinito se corta a los 3 segundos — aun así, asegúrate de que todo bucle tenga salida. Tu código se guarda solo mientras escribes.

¿Atascado? Pistas

Pista 1 — Necesitas la línea entera, no una palabra

cin >> word se detiene en el primer espacio: con the quick brown fox solo obtendrías the. cin.getline(line, 205) lee hasta el salto de línea — espacios incluidos —, que es justo lo que necesita una frase.

Pista 2 — Dos índices recorren la línea

Lleva un índice i avanzando. Al caer en una letra, guarda con un segundo índice dónde empieza la palabra y copia hasta chocar con un espacio o '\0'. Ese par inicio/fin es una palabra. Guarda cada palabra en un array bidimensional tipo char words[50][105]: la fila k es la palabra número k.

Pista 3 — Escribe las filas al revés

Si guardaste count palabras, la última está en la fila count - 1. Un for de count - 1 a 0 las escribe al revés; pon un espacio entre palabras, no después de la última. Varios espacios seguidos se colapsan en uno en la salida: da igual, el juez solo mira la secuencia de palabras.

Solución (¡inténtalo primero!)
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char line[205];
    cin.getline(line, 205);

    char words[50][105];
    int count = 0;
    int i = 0;
    while (line[i] != '\0') {
        while (line[i] == ' ') i++;
        if (line[i] == '\0') break;
        int j = 0;
        while (line[i] != '\0' && line[i] != ' ') {
            words[count][j] = line[i];
            i++;
            j++;
        }
        words[count][j] = '\0';
        count++;
    }

    for (int k = count - 1; k >= 0; k--) {
        cout << words[k];
        if (k > 0) cout << " ";
    }
    cout << endl;
    return 0;
}

Este bucle de separar y guardar es la misma maquinaria que usa Contar palabras para contar en vez de guardar: cambia una sola acción. Un extra que vale la pena: mientras escribes, cuenta también las palabras y muestra el total en una segunda línea. El siguiente paso con cadenas es recorrerlas desde los dos extremos a la vez en Cadena palíndromo.

Análisis profundo

Por qué funciona

Una frase no es un token — es una secuencia de tokens. El patrón es escanear, cortar, guardar: recorre la línea con un índice, corta cada palabra con el segundo, guárdalas en un array y desde entonces las posees en el orden que quieras. Separar-para-procesar reaparece en todas las tareas de texto, de contar palabras a parsear CSV.

El coste

Una pasada para separar y otra para escribir: O(L) de tiempo para una línea de longitud L, y O(L) de espacio extra para las palabras. Con L ≤ 200 no es nada — el mismo código aguantaría una línea de 100.000 caracteres.

Dónde falla

  • Leer con cin >> s en vez de cin.getline — obtienes exactamente una palabra, todos los tests de varias palabras fallan y nada parece mal hasta que notas los espacios que faltan.
  • Olvidar la '\0' tras copiar una palabra a su fila. Sin el terminador, cout << words[k] sigue escribiendo lo que haya al lado en memoria.

Siguiente paso

El mismo bucle de escanear y cortar cuenta palabras en lugar de guardarlas en Contar palabras — cambia lo que haces con cada trozo y es un problema nuevo.

Dos cosas para recordar

  • cin >> lee una palabra; cin.getline lee la línea entera — elige según la entrada, no por costumbre.
  • Invertir palabras = guardarlas todas y escribir las filas al revés.
🐞 Esta versión falla: ábrela y pruébala

Copia la línea tal cual: las palabras no se mueven

#include <iostream>
using namespace std;

int main() {
    char line[205];
    cin.getline(line, 205);
    cout << line << endl;
    return 0;
}