Combinação de atributos

13 respostas
P

Olá, Pessoal!

Preciso combinar uma série de atributos, por exemplo: x1, x2, x3, x4, … , xn. Primeiramente irei analisar cada atributo separadamente e depois combiná-los em pares(x1x2, x1x3, x1x4, …), em trios(x1x2x3, x1x2x4, …) e assim sucessivamente, preciso de todas as combinações possíveis para cada etapa(duplas, trios, etc).

Gostaria de saber se alguém conhece alguma classe que realiza a combinação desses atributos.

Grata pela atenção! :slight_smile:

13 Respostas

B

Combinação no sentido de gerar vários conjuntos e deixar esses elementos dentro deles?

Em se tratando de conjunto com objetos não repetidos, uma classe Set seria uma boa escolha.

P

Olá, Renrutal!

Desculpe a minha falta de conhecimento, mas não consegui entender qual classe seria essa. A forma de armazenamento não é o que me “preocupa”, mas sim como irei fazer para gerar o conjunto sem repetições e usando todas as combinações possíveis. Você pode, por favor, me explicar sua idéia novamente?

Grata!

B

Bem, digamos que esses x1, x2, xn, sejam objetos do tipo Xis.

O conjunto sem repetições de combinações é um objeto do tipo Set>

Um conjunto, que tem outro conjunto dentro, que por sua vez guarda Xis. Aliás Set significa literalmente Conjunto, em inglês.

Eu imagino que os objetos possam ser guardados da seguinte maneira:

Xis x1 = new Xis();
Xis x2 = new Xis();
Xis x3 = new Xis();

Set<Set<Xis>> conjunto = new HashSet<Set<Xis>>();

Set<Xis> dupla = new HashSet<Xis>();
dupla.add(x1);
dupla.add(x2);

conjunto.add(dupla);

dupla = new HashSet<Xis>();
dupla.add(x1);
dupla.add(x3);

conjunto.add(dupla);

dupla = new HashSet<Xis>();
dupla.add(x2);
dupla.add(x3);

conjunto.add(dupla);

Set<Xis> tripla = new HashSet<Xis>();
tripla.add(x1);
tripla.add(x2);
tripla.add(x3);

conjunto.add(tripla);
Ao final conjunto terá [(x1,x2), (x1,x3), (x2,x3), (x1,x2,x3)]

Obs: Isso é só um exemplo, quando for programar você tem que generalizar p/ funcionar p/ todos os casos.

B

Agora para gerar os conjuntos… tô pensando. :lol:

Vai ser algo relacionado à divisão e resto de números inteiros, baseado na posição em que os Xis estão guardados referente ao que o usuário entrou, aproveitando também que Set por definição não deixa seus elementos se repetirem.

B
package testes;

import java.util.HashSet;
import java.util.Set;

public class Conjuntos
{
    public static void main(String[] args)
    {
        Set<Integer> entrada = new HashSet<Integer>();
        entrada.add(1);
        entrada.add(2);
        entrada.add(3);
        entrada.add(4);

        Set<Set<Integer>> conjunto = new HashSet<Set<Integer>>();
        conjunto.add(new HashSet<Integer>());
        
        for (Integer i : entrada)
        {
            Set<Set<Integer>> temp = new HashSet<Set<Integer>>();

            for (Set<Integer> sub : conjunto)
                temp.addAll(addAndFork(sub, i));

            conjunto = temp;
        }
        System.out.println(conjunto + ": " + conjunto.size());
    }

    private static Set<Set<Integer>> addAndFork(Set<Integer> sub, Integer n)
    {
        Set<Set<Integer>> conjunto = new HashSet<Set<Integer>>();

        conjunto.add(new HashSet<Integer>(sub)); // x

        sub.add(n);
        conjunto.add(sub); // (x,n)

        return conjunto;
    }
}

Ficou muito mais simples do que eu achava que ficaria. E bem mais legal pq descobri uma propriedade sobre conjuntos associativos, que chamei de Copia e Adiciona.

Digamos que um conjunto tenha n associações dentro dele. Quando você adiciona mais um elemento, o conjunto fica com aquelas n, mais a associação de cada um desses n com o elemento. E essa fórmula continua a mesma p/ cada iteração do conjunto.

P

Olá, Renrutal!

O que é Set<Set>?

Grata!

B

Conjunto de conjunto de Inteiros, uma notação do generics a partir do Java 5.

Declarar os tipos ajuda a controlar o que vai dentro deles.

Bani

Que solução diferente… hehe

Minha sugestão é usar a solução descrita aqui.

Outra que eu achei interessante é essa aqui, que usa uma representação em números binários.

B

Não é esquisito, é perspicaz:

O conjunto começa vazio:
[]

Depois adicionamos 1 à todos os subconjuntos, enquanto mantemos os subconjuntos que já estão lá:
[] [1] -> 1 adicionado à um conjunto vazio é 1.

agora adicionamos 2 seguindo a mesma lógica acima, adiciona enquanto mantém os anteriores.
[] [1] [2] [1,2] (adicionei 2 ao vazio, e ao 1)

agora 3, com a mesma lógica:
[] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3]

4 (perceba que o número de subconjuntos sempre dobra):
[] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3] [4] [1,4] [2,4] [1,2,4] [3,4] [1,3,4] [2,3,4] [1,2,3,4]

finalmente, com 5 temos 32 subconjuntos:
[] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3] [4] [1,4] [2,4] [1,2,4] [3,4] [1,3,4] [2,3,4] [1,2,3,4] [5] [1,5] [2,5] [1,2,5] [3,5] [1,3,5] [2,3,5] [1,2,3,5] [4,5] [1,4,5] [2,4,5] [1,2,4,5] [3,4,5] [1,3,4,5] [2,3,4,5] [1,2,3,4,5]

E assim vai. Compare lado a lado cada iteração:

0-> [ ]
1-> [ ] [1]
2-> [ ] [1] [2] [1,2]
3-> [ ] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3]
4-> [ ] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3] [4] [1,4] [2,4] [1,2,4] [3,4] [1,3,4] [2,3,4] [1,2,3,4]
5-> [ ] [1] [2] [1,2] [3] [1,3] [2,3] [1,2,3] [4] [1,4] [2,4] [1,2,4] [3,4] [1,3,4] [2,3,4] [1,2,3,4] [5] [1,5] [2,5] [1,2,5] [3,5] [1,3,5] [2,3,5] [1,2,3,5] [4,5] [1,4,5] [2,4,5] [1,2,4,5] [3,4,5] [1,3,4,5] [2,3,4,5] [1,2,3,4,5]

Ou com a soma inteira:
0-> [ ]
1-> [1]
2-> [2] [1,2]
3-> [3] [1,3] [2,3] [1,2,3]
4-> [4] [1,4] [2,4] [1,2,4] [3,4] [1,3,4] [2,3,4] [1,2,3,4]
5-> [5] [1,5] [2,5] [1,2,5] [3,5] [1,3,5] [2,3,5] [1,2,3,5] [4,5] [1,4,5] [2,4,5] [1,2,4,5] [3,4,5] [1,3,4,5] [2,3,4,5] [1,2,3,4,5]

B

Aliás, nem precisa usar Set, um List ele funciona tão bem quanto, já que nunca insere elementos iguais.

Bani

Eu tenho a impressão de que a sua forma, pela própria implementação do Set, tem uma complexidade de tempo um pouco pior do que as outras que encontrei na web. Sem usar Set talvez fique igual.

B

Acho que o pior que ele faz é ficar copiando o estado anterior da lista toda hora ao invés de usar a própria lista e adicionar os elementos baseados na mesma, o que poderia seria feito via iterator até um valor que seria o tamanho da lista anterior.

P

Muitíssimo obrigada pela ajuda!!! encontrei uma solução para meu problema e aprendi um pouco sobre o Generics :wink:

Saudações!

Criado 10 de maio de 2008
Ultima resposta 13 de mai. de 2008
Respostas 13
Participantes 3