[ Resolvido ] - Duvida para alterar método com Array para ArrayList

Olá pessoal, eu pedi uma mãozinha para fazer um metodo que pesquisava em um arraylist de filmes o título do filme com maior numero de letras diferentes, um amigo aqui do forum me respondeu com este método(que funciona perfeitamente):

class ContagemLetrasDistintas {  
    public static void main (String[] args) {  
        String s = "The quick brown fox jumps over the lazy dog.";  
        boolean[] b = new boolean [26]; // inicialmente todos os valores são "false"  
        for (int i = 0; i < s.length(); ++i) {  
            char ch = Character.toUpperCase (s.charAt (i));  
            if ('A' <= ch && ch <= 'Z') {  
                b[ch - 'A'] = true;  
            }  
        }  
        int contagemLetrasDistintas = 0;  
        for (int i = 0; i < b.length; ++i) {  
            if (b[i]) contagemLetrasDistintas++;  
        }  
        System.out.printf ("Existem %d letras distintas na string [%s]%n", contagemLetrasDistintas, s);  
    }  
}  

Só que na aula só aprendi até agora Arraylist e não array apenas, primeiro alterei o metodo dele pras minhas exigências e funcionou ok, tentei então mudar pra Arraylist e inicialmente não consegui, e achei que fosse porque arrayList não aceitasse tipos primitivos(que acho que não aceita mesmo, só objetos), mas perguntei pra um professor e o mesmo me informou que era apenas colocar o primeiro b do boolean maiúsculo que funcionaria(assim --> ) e funcionou mesmo, só que como eu alterei o método acima eu fiz algo errado, pois o meu com arrayList ta pegando letras repetidas, acho que por uma linha que não entendi… Essa linha que não sei o que faz:

if ('A' <= ch && ch <= 'Z') {  
                b[ch - 'A'] = true;   // <-- aqui
            }  

Como não sei o que faz não sei como por no meu método, inicialmente coloquei ali b.add(true), mas aí adiciona todas letras, inclusive as repetidas…

Como posso fazer pra mudar no arrayList e funcionar direito… O que usar em vez de b.add(true)?

Grato.

b.get(ch - 'A') = true;

Eu também não entendi para o que serve a linha

b[ch - 'A'] = true;   // <-- aqui  

Alguém pode explicar ?

Existe uma maneira bem mais simples se você estiver usando ArrayList. Ao invés de usar um ArrayList de Boolean, você pode usar um ArrayList de Character, inserindo todos os caracteres que ainda não existirem lá. Depois, o método size() de ArrayList retornará a contagem de letras lá dentro.

Um exemplo:

ArrayList<Character> letras = new ArrayList<Character>();
String s = "The quick brown fox jumps over the lazy dog.";
for (int i = 0; i < s.length(); ++i) {    
    char ch = Character.toUpperCase (s.charAt (i));    
    if ('A' <= ch && ch <= 'Z') {    
        // sabemos que é uma letra, agora temos que verificar se ela 
        // já não está no ArrayList
        // DICA: use o método contains()
        // se não contiver, adicione a letra lá (método add())
    }    
} 
// agora, basta pegar a contagem de letras no ArrayList
// método size()

class ContagemLetrasDistintas { public static void main (String[] args) { String s = "The quick brown fox jumps over the lazy dog."; boolean[] b = new boolean [26]; // inicialmente todos os valores são "false" for (int i = 0; i < s.length(); ++i) { // roda as palavras do título char ch = Character.toUpperCase (s.charAt (i)); //passa o caracter atual para maiusculo e joga numa variavel char if ('A' <= ch && ch <= 'Z') { // verifica se é uma letra entre A e Z b[ch - 'A'] = true; // se for, seta o valor do boolean para true. } } int contagemLetrasDistintas = 0; for (int i = 0; i < b.length; ++i) { if (b[i]) contagemLetrasDistintas++; // se o valor estiver verdadeiro, ou seja, se essa letra está na palavra, incrementa o contador. } System.out.printf ("Existem %d letras distintas na string [%s]%n", contagemLetrasDistintas, s); } }

Coloquei alguns comentários pra ajudar ^^

O codigo verifica quantas das 26 letras aparecem na palavra.
Se uma letra apareceu, no seu indice do vetor de booleans, o valor e alterado para True.
Depois só é feita a contagem dos valores verdadeiros.

[quote=andre.almeida]class ContagemLetrasDistintas { public static void main (String[] args) { String s = "The quick brown fox jumps over the lazy dog."; boolean[] b = new boolean [26]; // inicialmente todos os valores são "false" for (int i = 0; i < s.length(); ++i) { // roda as palavras do título char ch = Character.toUpperCase (s.charAt (i)); //passa o caracter atual para maiusculo e joga numa variavel char if ('A' <= ch && ch <= 'Z') { // verifica se é uma letra entre A e Z b[ch - 'A'] = true; // se for, seta o valor do boolean para true. } } int contagemLetrasDistintas = 0; for (int i = 0; i < b.length; ++i) { if (b[i]) contagemLetrasDistintas++; // se o valor estiver verdadeiro, ou seja, se essa letra está na palavra, incrementa o contador. } System.out.printf ("Existem %d letras distintas na string [%s]%n", contagemLetrasDistintas, s); } }

Coloquei alguns comentários pra ajudar ^^

O codigo verifica quantas das 26 letras aparecem na palavra.
Se uma letra apareceu, no seu indice do vetor de booleans, o valor e alterado para True.
Depois só é feita a contagem dos valores verdadeiros.[/quote]
Obrigado pelas dicas, mas eu só não entendi como esta linha adiciona true no array somente quando o char não apareceu antes, ignorando repetidos… b[ch - 'A'] = true; // se for, seta o valor do boolean para true. Como saber se a letra ja esta no array?
Entendi como fazer usando o contains() no arrayList, só que ta dando resultado errado, o que será que esta mal?

fiz o seguinte:

  public Filme maisLetrasDiferentes() {
        int resultado = 0, guardaResultado = 0;
        Filme x = null;
        
        for (Filme f : lista) {
            String s = f.getTitulo();
            resultado = 0;
            ArrayList<Character> b = new ArrayList<Character> ();
            for (int i = 0;i < s.length();i++) {
                char ch = Character.toUpperCase(s.charAt(i));
                if ('A' <= ch && ch <= 'Z') { 
                    if (b.contains(ch) == false)
                        b.add(ch);
                }
            } resultado = b.size();
            if (guardaResultado < resultado)
                guardaResultado = resultado;
                x = f;
            }
            return x;
        }

Alguém poderia me dar uma luz… pois ainda preciso fazer um método mais complicado que é parecido com este, mas mais complicadinho, pois tenho que verificar qual o ator tem mais letras em comum com o título do filme, e um filme tem um arrayList de atores…

Grato e desculpe a pressa, é que ta próximo da entrega… :slight_smile:

A lógica do seu código me parece estar boa mas ele tem um sério problema de identação (pelo menos do jeito que você postou): há ‘if’s’ fora do ‘for’, sendo que deveria estar dentro, e comandos que deveriam estar dentro do ‘if’ que estão fora.

De qualquer forma, com base no seu código fiz esse exemplo aqui (que funciona). Basta adaptá-lo agora:

import java.util.ArrayList;

public class ContagemDeLetras {

	public static String[] listaDeStrings = { "opa!",
			"asdoaksdodsoadaksdkoasd", "abcdefgh",
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
			"abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg" };

	public static String maisLetrasDiferentes() {
		int resultado = 0, guardaResultado = 0;
		String x = null;

		for (String s : listaDeStrings) {
			resultado = 0;
			ArrayList<Character> b = new ArrayList<Character>();
			for (int i = 0; i < s.length(); i++) {
				char ch = Character.toUpperCase(s.charAt(i));
				if ('A' <= ch && ch <= 'Z') {
					if (b.contains(ch) == false)
						b.add(ch);
				}
			}
			resultado = b.size();
			if (guardaResultado < resultado) {
				guardaResultado = resultado;
				x = s;
			}
		}
		return x;
	}

	public static void main(String[] args) {
		System.out.println(maisLetrasDiferentes());
	}

}

[quote=marcobiscaro2112]A lógica do seu código me parece estar boa mas ele tem um sério problema de identação (pelo menos do jeito que você postou): há ‘if’s’ fora do ‘for’, sendo que deveria estar dentro, e comandos que deveriam estar dentro do ‘if’ que estão fora.

De qualquer forma, com base no seu código fiz esse exemplo aqui (que funciona). Basta adaptá-lo agora:

[code]
import java.util.ArrayList;

public class ContagemDeLetras {

public static String[] listaDeStrings = { "opa!",
		"asdoaksdodsoadaksdkoasd", "abcdefgh",
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		"abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg" };

public static String maisLetrasDiferentes() {
	int resultado = 0, guardaResultado = 0;
	String x = null;

	for (String s : listaDeStrings) {
		resultado = 0;
		ArrayList<Character> b = new ArrayList<Character>();
		for (int i = 0; i < s.length(); i++) {
			char ch = Character.toUpperCase(s.charAt(i));
			if ('A' <= ch && ch <= 'Z') {
				if (b.contains(ch) == false)
					b.add(ch);
			}
		}
		resultado = b.size();
		if (guardaResultado < resultado) {
			guardaResultado = resultado;
			x = s;
		}
	}
	return x;
}

public static void main(String[] args) {
	System.out.println(maisLetrasDiferentes());
}

}
[/code][/quote]

Muito obrigado amigo, realmente somente dei uma ajustada no for e funcionou ok agora… Só deixei o for assim e funcionou:

for (int i = 0;i < s.length();i++) { char ch = Character.toUpperCase(s.charAt(i)); if ('A' <= ch && ch <= 'Z' && b.contains(ch) == false) { b.add(ch); resultado = b.size(); } if (guardaResultado < resultado){ guardaResultado = resultado; x = f; } }

Aproveitando o post, como é relacionado ao mesmo assunto, será que não é pedir demais pra me tirarem uma outra dúvida, eu estava lendo sobre Collections e vi que um Set guarda objetos que não se repete, pensei em fazer um Set do tipo Char recebendo por exemplo letra por letra de minha String(o titulo do filme), com isso ja iria ter no Set só as que não se repetem, ,mas não consegui implementar, isso me ajudaria a simplificar o código do último método que me falta, que é como citei acima, ver o titulo do filme e o nome de ator por ator do elenco(arraylist de atores) pra ver quem tem mais letras em comum com o título do filme, isso pra todos meus mais de 250 filmes e retornar dentre todos o que mais letras em comum tem.

Tentei umas maluquices, mas até funcionou mas sem eficiência. se puderem me dar uma idéia agradeço. Primeiramente tentei fazer dois arraylist de char um para o titulo e outro para cada ator, tirar as letras repetidas de cada um, depois compara as posições e ver quais letras de um contém no outro e guardar o numero, e assim por diante em todos atores de todos os filmes, mas ficou muito grande e meio que me perdi na lógica…

Até mais,

Realmente um Set não permite duplicatas. E algumas implementações dele são HashSet (acho que se aplica, pois não leva em consideração a ordem), LinkedHashSet (mantém a ordem dos elementos) e TreeSet (ordena usando um Comparator).

Mas eu acho que não entendi muito bem ainda. Agora seu objetivo é fazer o que com o título e o nome dos atores?

[quote=marcobiscaro2112]Realmente um Set não permite duplicatas. E algumas implementações dele são HashSet (acho que se aplica, pois não leva em consideração a ordem), LinkedHashSet (mantém a ordem dos elementos) e TreeSet (ordena usando um Comparator).

Mas eu acho que não entendi muito bem ainda. Agora seu objetivo é fazer o que com o título e o nome dos atores?[/quote]

Preciso fazer um metodo que retorne o ator que tem mais letras em comum com o título do filme, ou seja, acessa o primeiro filme e após verifica um por um dos atores do filme(atributo do filme do tipo arraylist) o que tem mais letras em comum com o nome do filme, depois que ver todos os atores do filme, passa pro proximo filme… No final tenho que ter “guardado” o ator que tem mais letras em comum com o titulo do filme. Espero ter explicado melhor.

Grato,

Nesse caso, o maior problema não é o código e sim lógica, certo?

Esboce, com calma, como seu programa funcionará (um fluxograma, por exemplo) e poste aqui no fórum.

Aí, se ainda houver dúvidas quanto à utilização de estruturas como vetores, List ou Set, nós te damos um força, ok?

[quote=marcobiscaro2112]Nesse caso, o maior problema não é o código e sim lógica, certo?

Esboce, com calma, como seu programa funcionará (um fluxograma, por exemplo) e poste aqui no fórum.

Aí, se ainda houver dúvidas quanto à utilização de estruturas como vetores, List ou Set, nós te damos um força, ok?[/quote]

Obrigado pela força, consegui fazer o metodo. Fiquei mais de 2 horas até conseguir corrigir tudo, mas ta ok agora. Passei um trabalho pra descobrir que como eu estava trabalhando com arrayLists de char que iam se enchendo de letras e cada vez mais tinham letras em comum, até que me liguei e depois de comparar eu limpava o arrayList (com x.clear()), não sei se tem outra maneira mais fácil, mas funcionou bem.

Grande abraço e até breve, pois nas “férias” pretendo dar uma estudada em interface gráfica, pois este semestre nem chegamos a ver isso… E como começarei sozinho, me adiantando pro semestre que vem, vou precisar do GUJ pra tirar as dúvidas, que incondicionalmente virão :).

[quote=jefers0n][quote=marcobiscaro2112]Nesse caso, o maior problema não é o código e sim lógica, certo?

Esboce, com calma, como seu programa funcionará (um fluxograma, por exemplo) e poste aqui no fórum.

Aí, se ainda houver dúvidas quanto à utilização de estruturas como vetores, List ou Set, nós te damos um força, ok?[/quote]

Obrigado pela força, consegui fazer o metodo. Fiquei mais de 2 horas até conseguir corrigir tudo, mas ta ok agora. Passei um trabalho pra descobrir que como eu estava trabalhando com arrayLists de char que iam se enchendo de letras e cada vez mais tinham letras em comum, até que me liguei e depois de comparar eu limpava o arrayList (com x.clear()), não sei se tem outra maneira mais fácil, mas funcionou bem.

Grande abraço e até breve, pois nas “férias” pretendo dar uma estudada em interface gráfica, pois este semestre nem chegamos a ver isso… E como começarei sozinho, me adiantando pro semestre que vem, vou precisar do GUJ pra tirar as dúvidas, que incondicionalmente virão :).
[/quote]

Ótimo. Que bom que tudo funcionou. E tendo dúvidas, volte a procurar o fórum sim! :smiley:

Boa sorte com seus estudos!