[ Resolvido ] - Dúvida de como realizar pesquisa

11 respostas
J

Boa noite,

Estou quase finalizando meu trabalho de final de semestre de Algorítmos e programação… Só me falta fazer um método que retorne o ator que mais participou de filmes, explicarei abaixo ± a estrutura dos dados…

Tenho uma classe Filme e um de seus atributos é um arrayList elenco(com todos personagens que participaram do filme), eu preciso saber dentre todos os filmes o ator que mais participou de filmes…

Tentei fazer uma coisa que achei meio louca, que foi: criar um array com todos os personagens de todos os filmes e depois ir comparando e contando quantas vezes cada um aparece e guardar o que mais apareceu na lista… mas tive dificuldade de implementar, na verdade não consegui fazer, consegui com uma String recebendo todo mundo, mas daí fica difícil de pesquisar dentro da string depois…

Se alguém puder me dar uma idéia agradeço.

Grato,

11 Respostas

nel

Bom dia. Antes de mais nada, você deve garantir que para um elenco do seu filme não haja nomes repetidos concorda? Se usar o primeiro nome igual utilize o sobrenome para diferenciar. O que você pode fazer é armazenar todos os filmes em um List. Para cada filme, temos uma lista de atores perfeito?

Pensei em algo rápido, mas é uma ideia. Você pode criar um Map<String, Integer> onde a String (key) será o nome do ator e o Integer (value) será a quantidade de vezes que ele aparece para cada filme. Ou seja, você percorre sua lista de filmes e em seguida sua lista de atores (está contida em filmes) e verifica, se o ator de cada posição da lista não estiver no Map você adiciona, caso exista, soma +1. É uma ideia.

Abraços.

J

nel:
Bom dia. Antes de mais nada, você deve garantir que para um elenco do seu filme não haja nomes repetidos concorda? Se usar o primeiro nome igual utilize o sobrenome para diferenciar. O que você pode fazer é armazenar todos os filmes em um List. Para cada filme, temos uma lista de atores perfeito?

Pensei em algo rápido, mas é uma ideia. Você pode criar um Map<String, Integer> onde a String (key) será o nome do ator e o Integer (value) será a quantidade de vezes que ele aparece para cada filme. Ou seja, você percorre sua lista de filmes e em seguida sua lista de atores (está contida em filmes) e verifica, se o ator de cada posição da lista não estiver no Map você adiciona, caso exista, soma +1. É uma ideia.

Abraços.

Nunca tinha visto hashMap ainda, dei uma lida na API, mas não entendi muito bem, se eu entendi direito o que explicaste, eu vou percorrer a lista de filmes colocando os atores(de cada filme) neste map, se o ator ja tinha sido incluido no filme anterior por exemplo e ele aparece novomente ele incrementa este ator, daí qdo percorrer todo o arraylist de filmes estará guardado a quantidade que cada um apareceu nos filmes?

Se é isso, como eu saberia qual deles é o maior(que apareceu mais vezes…), entendi a idéia, mas fei uma olhada na API pra ver se ajudava a implementar mas ta difícil…

Se alguém puder me dar uma luz… :slight_smile:

Por exemplo:

ArrayList<Filme> lista = new ArrayList<Filme> ();  //criei um arrayList de filmes e agora como faço pra usar o HashMap nele?
     for (Filme f : lista) {
         // ??? 
     }
CrOnNoS

As subclasses de Map funcionam como uma List qualquer, mas com 2 valores, uma "Key" e o conteúdo salvo naquela Key.
É como em banco de dados, você tem sua tabela de Usuários onde sua Key é um ID por exemplo que nunca será repetido, e para cada ID você tem os valores (nome, idade etc etc)
A idéia que o nei te deu foi você salvar a lista de atores em um Map onde a Key é o nome do ator (que nunca se repete) e você usaria o segundo atributo para salvar um valor int (Integer) que representaria quantas vezes esse ator foi atribuido a um filme, ou seja, primeiramente você adicionaria o ator na Map colocando o valor do int como 0, e sempre que esse ator for adicionao a um filme, você incrementaria esse inteiro inicializado em 0 fazendo ele salvar em quantos filmes aquele ator participou.
Depois bastaria iterar no seu Map e buscar a key (nome do ator) que tem o valor mais alto.

Sobre sua primeira solução que seria mais dispendiosa, segue alguns métodos que poderia te ajudar com sua ArrayList contendo todos os personagens de todos os filmes:
Set<String> atoresSemRepeticao = new HashSet<String>(atores);
Criaria um objeto Set tomando base sua lista de atores. Lembrando que "Set" (Conjunto) não possui elementos repetidos, então esse Set teria todos os atores contidos no ArrayList "atores" mas sem repeti-los. Agora, tendo a ArrayList e o Set em mãos, você pode iterar o Set e usar o seguinte método para ver quantas vezes aquele nome aparece no ArrayList:
Collections.frequency(atores, iteradorParaSet.next());
Esse método retorna o número de vezes que o segundo parâmetro aparece na Collection passada como primeiro parâmetro Um exemplo de como ficaria:
ArrayList<String> atores = new ArrayList<String>();
		atores.add("Manuel");
		atores.add("Ronaldo");
		atores.add("Talita");
		atores.add("Ana");
		atores.add("Manuel");
		atores.add("Roberto");
		atores.add("Talita");
		atores.add("Ronaldo");
		atores.add("Talita");
		atores.add("Manuel");

		Set<String> atoresSemRepeticao = new HashSet<String>(atores);

		int quantidadeDeFilmesDoAtorSalvo = 0;
		int quantidadeDeFilmesDoAtorAtual;
		String atorSalvo = "";
		String atorAtual;
		Iterator<String> iteradorParaSet = atoresSemRepeticao.iterator();

		while (iteradorParaSet.hasNext()) {
			atorAtual = iteradorParaSet.next();
			quantidadeDeFilmesDoAtorAtual = Collections.frequency(atores,
					atorAtual);
			if (quantidadeDeFilmesDoAtorAtual > quantidadeDeFilmesDoAtorSalvo) {
				quantidadeDeFilmesDoAtorSalvo = quantidadeDeFilmesDoAtorAtual;
				atorSalvo = atorAtual;
			}
		} // while

		System.out.println(atorSalvo);

Sendo o ArrayList atores uma representação do seu array.

J

CrOnNoS, muito obrigado pela atenção, tentei usar tuas dicas mas não esta compilando ainda, acho que devido ao tipo de meus dados, meu arrayList de de atores que é atributo de cada filme é do tipo Personagem, que é uma classe que só tem os atributos astro e seu nome, e este astro é do tipo Astro, outra classe que só tem atributo nome(String)… Acho que só pra dar uma complicada no trabalho…

Fiz isso nas dicas que deste:

public String maisParticipacoes() {
        ArrayList<Personagem> atores = new ArrayList<Personagem>();
        
        for (Filme f : lista) {
           ArrayList x = f.listaElenco();                    //aqui tentei pôr todos os atores de cada filme emum mesmo array x.
           for (int pos = 0; pos < x.size();pos++) {
               Personagem y = f.listaElenco().get(pos) // aqui tento pegar cada ator e adicionar no personagem y, o listaElenco é um metodo que retorna um arrayList com os atores de um filme(neste caso todos de um filme em cada passada do for), mas ta dando erro,pois meu "f" é do tipo Filme, e eu preciso que meu "y" seja ou String, ou Personagem, que é o tipo do conteudo do array elenco(dos atores).
               atores.add(y);                                      
            }                                                           
        }
        
        Set<String> atoresSemRepeticao = new HashSet<String>(atores);
        
        int quantidadeDeFilmesDoAtorSalvo = 0;  
        int quantidadeDeFilmesDoAtorAtual;  
        String atorSalvo = "";  
        String atorAtual;  
        
        Iterator<String> iteradorParaSet = atoresSemRepeticao.iterator();  
  
        while (iteradorParaSet.hasNext()) {  
            atorAtual = iteradorParaSet.next();  
            quantidadeDeFilmesDoAtorAtual = Collections.frequency(atores, atorAtual);  
            if (quantidadeDeFilmesDoAtorAtual > quantidadeDeFilmesDoAtorSalvo) {  
                quantidadeDeFilmesDoAtorSalvo = quantidadeDeFilmesDoAtorAtual;  
                atorSalvo = atorAtual;  
            }
        }
        return atorSalvo;
    }

To meio perdido, só falta isso e ontem ja tentei e nada, se alguém puder me auxiliar agradeço, emobra esteja meio grande a pergunta… :slight_smile:

Até+

nel

Bom dia.

Fiz aqui com Map e funcionou, mas fiz para aparecer apenas um ator:
Map<String, Integer> map = new HashMap<String, Integer>();
		 
		 List<String> atores = new ArrayList<String>();		 
		 atores.add("Maria");
		 atores.add("Joao");
		 atores.add("Maria");
		 atores.add("Jose");
		 atores.add("Joao");
		 atores.add("Jose");
		 atores.add("Jose");
		
		 
		 for (String string : atores) {
			 //primeira vez que o ator aparece
			 if(map.get(string) == null){
				map.put(string, 1);
			} else {
				Integer i = map.get(string);
				i++;
				map.put(string, i);
			}
		}
		int maior = 0;
		String nome = "";		
		Collection<Integer> values = map.values();
		for (Integer integer : values) {
			if(integer > maior){
				maior = integer;
			}
		}
		//pega todas as keys do map
		Set<String> set = map.keySet();
		for (String nomes : set) {
			Integer value = map.get(nomes);
			if(value.intValue() == maior) {
				nome = nomes;
			}
		}
		System.out.println("Ator: "+nome);
	}

Dois detalhes, se quiser mostrar mais do que um ator, exemplo, o ator Joao e Jose aparecem duas vezes, substitua a linha que contém a String nome = ""; por uma List list = new ArrayList(); e ao invés de nome = nomes você faz list.add(nomes) perfeito? Já ia esquecendo, o int maior deve ser uma lista também, já que você pode ter valores iguais! :)

Outro detalhe, talvez tenha que mudar algo para a sua necessidade, mas a ideia é esta.

Abraços! :)

J
nel:
Bom dia. Fiz aqui com Map e funcionou, mas fiz para aparecer apenas um ator:
Map<String, Integer> map = new HashMap<String, Integer>();
		 
		 List<String> atores = new ArrayList<String>();		 
		 atores.add("Maria");
		 atores.add("Joao");
		 atores.add("Maria");
		 atores.add("Jose");
		 atores.add("Joao");
		 atores.add("Jose");
		 atores.add("Jose");
		
		 
		 for (String string : atores) {
			 //primeira vez que o ator aparece
			 if(map.get(string) == null){
				map.put(string, 1);
			} else {
				Integer i = map.get(string);
				i++;
				map.put(string, i);
			}
		}
		int maior = 0;
		String nome = "";		
		Collection<Integer> values = map.values();
		for (Integer integer : values) {
			if(integer > maior){
				maior = integer;
			}
		}
		//pega todas as keys do map
		Set<String> set = map.keySet();
		for (String nomes : set) {
			Integer value = map.get(nomes);
			if(value.intValue() == maior) {
				nome = nomes;
			}
		}
		System.out.println("Ator: "+nome);
	}

Dois detalhes, se quiser mostrar mais do que um ator, exemplo, o ator Joao e Jose aparecem duas vezes, substitua a linha que contém a String nome = ""; por uma List list = new ArrayList(); e ao invés de nome = nomes você faz list.add(nomes) perfeito? Já ia esquecendo, o int maior deve ser uma lista também, já que você pode ter valores iguais! :)

Outro detalhe, talvez tenha que mudar algo para a sua necessidade, mas a ideia é esta.

Abraços! :)

Obrigado pela dica, só quero que mostre um mesmo(o que mais participou dos filmes), até funciona assim passando direto os atores... Mas no meu caso acho que estou "viajando" na hora de pegar os dados dos atores, pois preciso trabalhar com os dados existentes no trabalho...

Fiz isso, mas ta difícil...:
public String maisParticipacoes() { 
        
    Map<Astro, Integer> map = new HashMap<Astro, Integer>();  
       
     List<String> atores = new ArrayList<String>();        

        for (Filme f : lista) {  // aqui ta a dificuldade, tenho que percorrer minha lista Filmes e pegar cada personagem d dentro da lista personagens(atributo do filme)...
           for (int x = 0;x < f.listaPersonagens().size();x++) { // o metodo listaPersonagens() cria um arraylist do tipo String com o elenco do filme.
                atores.add(f.listaPersonagens().get(x)); // <-- aqui da o erro: cannot find symbol - method add(java.lang.Object)
            }
        }
       // pra baixo ta igual o teu exemplo, só um return nome em vez de escrever o ator...

Desculpe o amadorismo, mas até sei que devo estar errando em algo muito básico... :) pois o mais difícil ta funcionando...

Até +

tiagoscd

Na realidade, se tu colar o método listaPersonagens() fica mais fácil para auxiliar. Mas por acaso já tentou atribuir a lista de personagens para um objeto para em seguida adicionar a lista de atores?

String o = (String) f.listaPersonagens().get(x); atores.add(o);

Aparentemente o erro se dá pelo fato de estar tentando adicionar um objeto do tipo Object em uma lista do tipo String.

J

tiagoscd:
Na realidade, se tu colar o método listaPersonagens() fica mais fácil para auxiliar. Mas por acaso já tentou atribuir a lista de personagens para um objeto para em seguida adicionar a lista de atores?

String o = (String) f.listaPersonagens().get(x); atores.add(o);

Aparentemente o erro se dá pelo fato de estar tentando adicionar um objeto do tipo Object em uma lista do tipo String.

Pode ser isso mesmo, vou tentar e ja posto…

Grato tiagoscd

J

tiagoscd:
Na realidade, se tu colar o método listaPersonagens() fica mais fácil para auxiliar. Mas por acaso já tentou atribuir a lista de personagens para um objeto para em seguida adicionar a lista de atores?

String o = (String) f.listaPersonagens().get(x); atores.add(o);

Aparentemente o erro se dá pelo fato de estar tentando adicionar um objeto do tipo Object em uma lista do tipo String.

Muito obrigado, funcionou. A princípio achei que não porque continuava não compilando, mas aí voltei aqui e vi que tinha esquecido o cast pra String… ai deu certo.

Valeu.

edmarr

Não esqueça de editar o tópico , se estiver satisfeito eh claro .
Ou ainda tem alguma duvida ?

J

edmarr:
Não esqueça de editar o tópico , se estiver satisfeito eh claro .
Ou ainda tem alguma duvida ?

Claro amigo, acabei de fazer isso.

Obrigado a todos mais uma vez.

Criado 28 de novembro de 2009
Ultima resposta 1 de dez. de 2009
Respostas 11
Participantes 5