Inverter frase com pilha

Olá pessoal!

Estou criando um código que faça a inversão de uma frase digitada pelo usuário usando uma pilha.

O que fiz ficou assim:

public interface Stack {
    public int size();
    public boolean isEmpty();
    public void push(Object str);
    public Object pop();
    public Object top();
}
public class Pilha implements Stack{
    private int capacidade,ultimo; // capacidade e ultimo item a entrar no vetor
    private Object[] vetor;
    public Pilha(){
        this(100);
    }
    public Pilha(int capacidade){
       this.capacidade = capacidade;
       vetor = new Object[this.capacidade];
       ultimo = -1; //o vetor não possui itens na construção
    }
    
    public int size() {
        return (ultimo + 1);
    }

    public boolean isEmpty() {
        return (ultimo < 0);
    }
    public boolean isFull(){
        return (ultimo >= (this.capacidade - 1));
    }

    public void push(Object obj) {
        if (isFull()){
            System.out.println("Pilha cheia");
        }
        vetor[++ultimo] = obj;
    }

    public Object pop() {
        if (isEmpty()){
            System.out.println("Pilha vazia");
        }
        return (vetor[ultimo--]);
    }

    public Object top() {
        return (vetor[ultimo]);
    }
    
    public int tam(){
        return vetor.length;
    }
    
    public void imprimirRetirar(){
        for (int i = 0; i < tam(); i++){
            System.out.println(pop());
        }
    }
    public void apenasImprimir(){
        for(int i = (size()-1); i > 0; i--){
            System.out.println(vetor[i]);
        }
    }
}
import java.util.Scanner;

public class InverteFrase {
    private Pilha pilha;
    private Object frase;
    private int capacidade;

    //construtor
    public InverteFrase(int capacidade){
        this.capacidade = capacidade;
        pilha = new Pilha(this.capacidade);
        frase = null;
    }
    
    //empilha palavras
    public void setFrase(Object palavra){
        if(pilha.isFull()){
            return;
        }
        this.frase = palavra;
        pilha.push(this.frase);
    }
    
    //desempilha palavras
    public Object getFrase(){
        if(pilha.isEmpty()){
            return null;
        }
        return pilha.pop();
    }
    
    //inverte o conteúdo da pilha e imprime
    public void getImprimePilhaInvertida(){
        for (int i = 0; i < pilha.tam(); i++) {
            System.out.print(pilha.pop());
        }
    }
            

    public static void main(String args[]){
        int temp = 0;
        Scanner leitor = new Scanner(System.in);
        
        System.out.println("Quantas palavras tem sua frase? ");
        
        temp = leitor.nextInt();
        
        InverteFrase frase = new InverteFrase(temp);
        
        System.out.println("Digite a primeira palavra: ");
        
        for (int i = 0; i < temp; i++ ){
            frase.setFrase(leitor.next() + " ");
            if (i < (temp - 1)){
            System.out.println("Digite a próxima palavra: ");            
            }
        }
        System.out.println("\nSua frase invetida ficou assim:");
        frase.getImprimePilhaInvertida();
        System.out.println();
    }
}

Como os senhores puderam perceber, no meu programinha é preciso que o usuário primeiramente digite o número de palavras existentes na frase que irá digitar.

Gostaria de aprimorá-lo para que o usuário já digite diretamente a frase completa e o programa conte o número de palavras existentes na frase, separe-as, empilhe-as e em seguida a imprima invertida.

Alguém pode me ajudar na criação desse algoritmo?

Você pode utilizar uma estrutura dinâmica para armazenar as palavras (um ArrayList, por exemplo). Isso exigiria alterações na classe pilha.

Pode também ler todas as palavras e contar. Quando o usuário encerrar a digitação (pressionando apenas Enter, por exemplo), você instancia a pilha e empilha as Strings, o que exigiria alterações na classe InverteFrase.

Tornar a pilha dinâmica é a melhor solução na minha opinião.

Você precisa criar a pilha?

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Stack.html

[quote=davidtiagoconceicao]Você pode utilizar uma estrutura dinâmica para armazenar as palavras (um ArrayList, por exemplo). Isso exigiria alterações na classe pilha.

Pode também ler todas as palavras e contar. Quando o usuário encerrar a digitação (pressionando apenas Enter, por exemplo), você instancia a pilha e empilha as Strings, o que exigiria alterações na classe InverteFrase.

Tornar a pilha dinâmica é a melhor solução na minha opinião.[/quote]

Bicho, lance não está muito claro pra mim. A parada é a seguinte:

Vou receber uma string com vária palavras:
String frase = objeto.nextLine();

Depois tenho que contar as palavras desta frase:
Existe uma classe, ou alguma propriedade de String, que conta o nº de palavras?

Crio um array do tamanho do nº de palavras da frase:
Object array[] = new Object[qtdPalavras];

Separo palavra por palavra da frase e jogo cada uma em uma posição do array:
for (int cont = 0; cont < array.length; ++cont)
{
array[cont] = palavraX;
}

Pego os elementos do array e empilho:
for (int cont = 0; cont < array.length; ++cont)
{
pilha.push(array[cont]);
}

Imprimo a pillha:
System.out.printf("%s ", pilha.pop());

Pode me ajudar corrigindo o que fiz acima?

[quote=jairelton]Você precisa criar a pilha?

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Stack.html[/quote]

Velho, criei minha própria Stack para fixar melhor alguns conceitos… :wink:

A classe StringTokenizer conta quantas palavras tem uma string.

fica mais ou menos assim:

StringTokenizer s = new StringTokenizer("Frase digitada");

while(s.HasMoreTokens())
{
     System.out.println(s.nextToken());
}

Aí ele imprime em cada linha uma palavra, aí no seu caso faz isso e coloca um contador, assim vc saberá quantas palavras terá na string.
Acho que é isso.

[quote=douglastc]A classe StringTokenizer conta quantas palavras tem uma string.

fica mais ou menos assim:

StringTokenizer s = new StringTokenizer("Frase digitada");

while(s.HasMoreTokens())
{
     System.out.println(s.nextToken());
}

Aí ele imprime em cada linha uma palavra, aí no seu caso faz isso e coloca um contador, assim vc saberá quantas palavras terá na string.
Acho que é isso.[/quote]

Velho, acho que vc não entendeu o que eu desejo fazer…

[quote=cassius_fpu][quote=douglastc]A classe StringTokenizer conta quantas palavras tem uma string.

fica mais ou menos assim:

StringTokenizer s = new StringTokenizer("Frase digitada");

while(s.HasMoreTokens())
{
     System.out.println(s.nextToken());
}

Aí ele imprime em cada linha uma palavra, aí no seu caso faz isso e coloca um contador, assim vc saberá quantas palavras terá na string.
Acho que é isso.[/quote]

Velho, acho que vc não entendeu o que eu desejo fazer…[/quote]

vc não quer contar o número de palavras que tem em uma string? Pelo menos foi isso que eu entendi.

Mais fácil ainda, você pode usar split pra quebrar sua String. Aí você pode inserir item a item num loop (ou já imprimir num loop invertido, como no código abaixo, mas aí já perde a graça :slight_smile: )

public class PhraseInverter {

	public static void main(String[] args){
		System.out.println("Digite sua frase:");
		String input = (new Scanner(System.in)).nextLine();
		String[] words = input.split(" ");
		System.out.println("Aqui está a frase invertida:");
		for(int i = words.length - 1; i >= 0; i --){
			System.out.print(words[i] + " ");
		}
	}
}

[quote=rubinelli]Mais fácil ainda, você pode usar split pra quebrar sua String. Aí você pode inserir item a item num loop (ou já imprimir num loop invertido, como no código abaixo, mas aí já perde a graça :slight_smile: )

[code]
public class PhraseInverter {

public static void main(String[] args){
	System.out.println("Digite sua frase:");
	String input = (new Scanner(System.in)).nextLine();
	String[] words = input.split(" ");
	System.out.println("Aqui está a frase invertida:");
	for(int i = words.length - 1; i >= 0; i --){
		System.out.print(words[i] + " ");
	}
}

}
[/code][/quote]

Velhinho, a inversão deve se dar usando pilha…

Consegui terminar! Ficou assim:

public interface Stack {
    public int size();
    public boolean isEmpty();
    public void push(Object str);
    public Object pop();
    public Object top();
}
public class Pilha implements Stack{
    private int capacidade,ultimo; // capacidade e ultimo item a entrar no vetor
    private Object[] vetor;
    public Pilha(){
        this(100);
    }
    public Pilha(int capacidade){
       this.capacidade = capacidade;
       vetor = new Object[this.capacidade];
       ultimo = -1; //o vetor não possui itens na construção
    }
    
    public int size() {
        return (ultimo + 1);
    }

    public boolean isEmpty() {
        return (ultimo < 0);
    }
    public boolean isFull(){
        return (ultimo >= (this.capacidade - 1));
    }

    public void push(Object obj) {
        if (isFull()){
            System.out.println("Pilha cheia");
        }
        vetor[++ultimo] = obj;
    }

    public Object pop() {
        if (isEmpty()){
            System.out.println("Pilha vazia");
        }
        return (vetor[ultimo--]);
    }

    public Object top() {
        return (vetor[ultimo]);
    }
    
    public int tam(){
        return vetor.length;
    }
    
    public void imprimirRetirar(){
        for (int i = 0; i < tam(); i++){
            System.out.println(pop());
        }
        System.out.println();
    }
    
    public void apenasImprimir(){
        for(int i = 0; i <= tam()-1; ++i){
            System.out.println(vetor[i]);
        }        
        System.out.println();
    }    
}
import java.util.Scanner;

public class IverteFrase1{

    public static void main(String args[]){       
        Scanner input = new Scanner(System.in);        
        
        System.out.println("Digite uma frase");
        
        String frase = input.nextLine();//armazena frase 

        String[] ar = frase.split(" ");//cria array com palavras da frase
        
        //mostrando array
        System.out.println("\nImprimindo array:");
        for (int i = 0; i < ar.length; ++i){            
            System.out.printf("Elemento %d: %s\n", i, ar[i]);
        }
        
        //empilhando array        
        Pilha pilha = new Pilha(ar.length);        
        for (int cont = 0; cont < ar.length; ++cont){
            pilha.push(ar[cont]);
        } 

        //imprimindo pilha
        System.out.printf("\nPilhamento:\n");
        pilha.apenasImprimir();
        
        System.out.printf("\nDesempilhamento:\n");
        pilha.imprimirRetirar();        
    }
    
}

Obrigado a todos que ajudaram!