[RESOLVIDO] Ocorrencias de uma frase em arquivo ".txt"

Boa Noite,
Estou estudando Manipulação de Arquivos e estou com o seguinte problema:

Preciso criar um programa capaz de ler um arquivo, e mostrar a quantidade de ocorrências de uma determinada Palavra ou Frase fornecida pelo usuário.
Entrei no site da Oracle, e achei o “StringTokenizer” que resolveu meu problema para procurar palavras. Porém, meu programa não funciona para achar uma frase fornecida.
Eu fiz testes, e vi que o IndexOf() tambem não serve (ele não conta mais de uma ocorrência por linha). Alguem conhece alguma forma de eu resolver este problema com frase?

Segue abaixo o que já fiz usando StringTokenizer:

/**
 *
 * @author Guilherme
 */
import java.io.*;
import java.util.StringTokenizer;
import java.util.Scanner;

public class contarOcorrencias
{
    public static void main(String args[])
    {
    Scanner scan = new Scanner(System.in);

    String nomearquivo;
    String palavra;

    System.out.println("Informe o nome do arquivo: ");
    nomearquivo = scan.next();
    System.out.println("Informe o que deseja buscar: ");
    palavra=scan.next();

    int resposta = procura(nomearquivo,palavra);

    System.out.println("O total de ocorrencias é: "+resposta);
}

    public static int procura(String nomearquivo, String palavra)
    {
    int achou=0;
    String linha;
       try
       {
          BufferedReader in = new BufferedReader(new FileReader(nomearquivo));
          while ((linha = in.readLine()) != null)
          {
            StringTokenizer st = new StringTokenizer(linha);
               while (st.hasMoreTokens())
               {
                  if (st.nextToken().contains(palavra))
                  achou++;
               }
          }
       }
          catch (Exception e)
          {
            System.err.println("Erro na abertura do arquivo " + nomearquivo);
            return achou;
          }
    return achou;
    }
}

Ninguem conhece algum método, ou ao menos uma dica à respeito do problema?

Não é só ler o conteúdo do arquivo, armazenar em uma StringBuilder e usar o método contains de String no toString da StringBuilder?

StringBuilder conteudoDoArquivo = getConteudoDoArquivo("/home/andre/arquivo.txt");
String frase = "where is waldo?";

return conteudoDoArquivo.toString().contains(frase);

Andre, tentei implementar o que você falou… mas não obtive sucesso…
Se alguem tiver alguma idéia, poste aí. Vou continuar pesquisando alguma solução… Eu estava lendo sobre a API HashMap …parece que ela pode me ajudar… qualquer andamento na solução postarei aqui.

Se você leu a documentação do StringTokenizer, deveria ter visto o comentário ao final do Javadoc da classe, onde diz que a partir do Java 5 ela não deveria mais ser usada, e no lugar, deveria-se usar o método split da classe String, ou as classes do pacote java.util.regex.

Mas enfim, você pode fazer o seguinte:

  1. Procure a frase com index of.
  2. Retire o substring do texto do índice 0 até indexOf(frase)+tamanho frase
  3. Volte ao passo 1 até a String estar vazia.

Por exemplo:

“A vaca foi a vila, o micro é levado. Se a vaca foi a vila, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado.”

Vamos supor que a frase procurada seja “vaca foi a vila”.

Você acha, no índice 3:
“A vaca foi a vila, o micro é levado. Se a vaca foi a vila, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado.”

Conta 1.

Retira a substring:
, o micro é levado. Se a vaca foi a vila, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado."

Repete a busca, achando agora no índice 27:
, o micro é levado. Se a vaca foi a vila, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado."

Tira o substring:
, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado."

E repete o processo… até que a String termine.

Vinicius… simplesmente perfeito. Exatamente isso. Implementei e o seu algoritmo e funcionou perfeitamente; funciona tanto para Palavras como para Frases. Utilizei como critério de parada o retorno do IndexOf() igual a “-1”. E para apagar trechos da String criei uma pequena StringBuilder.
Agora percebi como compliquei… Eu já usei bastante o IndexOf(), substring, etc. E nem me passou pela cabeça que ferramentas tão simples dariam conta do problema.

Obrigado a todos pela ajuda. :smiley:

O pessoal gosta de tentar fazer malabarismo com o split, e muitas vezes a solução é mais simples do que parece. O algoritmo fica com o que? Umas 3 linhas?

[quote=ViniGodoy]O pessoal gosta de tentar fazer malabarismo com o split, e muitas vezes a solução é mais simples do que parece. O algoritmo fica com o que? Umas 3 linhas?
[/quote]
Sim, basicamente o “motor” do algoritmo são três linhas. Exatamente os três passos que você citou.
Se alguem quiser fazer um teste simples utilizando o exemplo do Vinícius, crie um “arquivo.txt” com o seguinte texto:
“A vaca foi a vila, o mico é levado. Se a vaca foi a vila, então o mico é levado. E foi porque a vaca foi a vila, que o mico se tornou levado.”

Ficou bem simples… para ficar um código mais limpo e fácil de entender, criei um programa básico sem utilizar JFrame:

import java.io.*;
public class contarOcorrencias
{
    public static void main(String args[])
    {
        String nomearquivo = "arquivo.txt"; //Nome do arquivo que você salvou. Deve estar no mesmo diretorio do programa na hora de executar.
        String pal="vaca foi a vila"; //Coloque aqui a frase ou palavra a ser buscada.

        int comp = pal.length(); //Conta o comprimento da palavra/frase a ser buscada. Auxilia la na frente na hora de deletar a frase.
        int saida = procura(comp,nomearquivo,pal);

        System.out.println("Total de Ocorrencias: "+saida);
    }

    public static int procura(int comp, String nomearquivo, String pal)
    {
    int achou=0;
    String linha;
    String texto="";
	 
        try {
        BufferedReader in = new BufferedReader(new FileReader(nomearquivo));
            while ((linha = in.readLine()) != null)
            {
            texto=""+texto+linha; //Isso aqui serve para evitar falhas caso o arquivo tenha mais de uma linha. Ele agrupa todo o texto em uma String.
	    }
	      System.out.println("Conteudo: \n"+texto); //Mostra todo o conteudo do arquivo.

            StringBuilder sb = new StringBuilder(texto);  //Criei essa String Builder para poder deletar a frase a medida que a busca vai sendo efetuada.
            int posicao=0;
				
	    posicao = sb.indexOf(pal);//Se nao encontrar nada logo na primeira busca, encerra o programa mostrando ZERO no total de Ocorrencias.

            while(posicao!=-1) //Criterio de parada
            {
            posicao = sb.indexOf(pal);
            sb.delete(0,posicao+comp);
            System.out.println(sb+"\n");//Apenas mostra as frases sendo cortadas.
            achou++;
            posicao = sb.indexOf(pal);
            }
         
        in.close();
        return achou;
        } catch (Exception e) {
          System.err.println("Erro na abertura do arquivo " + nomearquivo);
         }
       return achou;
    }
}