java: creación de una secuencia de múltiples tuplas a partir de un par de tuplas

CorePress2024-01-24  8

Digamos que tengo una tupla (1, 2). Quiero crear una secuencia que me brinde todas las combinaciones posibles de los valores de esas tuplas. Entonces quiero crear una transmisión que se vea así:

[(1, 1), (1, 2), (2, 1), (2, 2)]

Esta es mi clase para mis tupels:

public class Tupel<T> {

    private final T first;
    private final T second;

    public Tupel(T first, T second) {
        assert first != null;
        assert second != null;

        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }

    @Override

...

Esta es mi clase para mis pares de tuplas:

public class TupelPairs<T> {
    private TupleSet<T> tupleSet;

    public TupelPais(TupleSet<T> tupleSet) {
    this.tupelSet = tupleSet;
    //This is where I want to create my tuple pairs
    }

   
    public Stream<Tupel<T>> getElements() {
    return; //This is where I want to return my Stream of those tupel pairs
}

¿Cómo puedo crear esos pares de tuplas?

¿Qué es TupleSet en tu clase?

-code_mechanic

27 de marzo de 2021 a las 0:37

Es la interfaz en la que implementé un conjunto básico para todos mis otros conjuntos. Simplemente pensé que no importaría resolver mi pregunta, ya que solo quiero saber cómo crear esa transmisión

usuario15412162

27 de marzo de 2021 a las 0:43

usted dio un ejemplo de 2 números, pero el conjunto puede contener más de 2 valores, por lo que no es un poco confuso.

-code_mechanic

27 de marzo de 2021a las 0:46

Sí, tienes razón, en mi tarea implemento diferentes tipos de conjuntos con secuencias como números enteros, números naturales o simplemente un conjunto de números. Solo estaba tratando de explicar lo que estoy tratando de lograr dando un ejemplo sencillo.

usuario15412162

27 de marzo de 2021 a las 0:58

¿Cuál será tu conjunto de tuplas que tendrá una tupla de 2 valores o valores mismos?

-code_mechanic

27 de marzo de 2021 a las 1:06



------------------------------------

Primero necesitas producir cada par de tu conjunto y es la forma más fácil que se me ocurre ahora mismo

List<T> vals = new ArrayList(tupleSet);
Set<Tuple<T>> set = new HashSet();

for(int i = 0; i < vals.size() - 1; i++) {
  for (int j = i+1; j < vals.size(); j++) {
     set.add(new Tuple(vals.get(i), vals.get(j)));
  }
}

Ahora, para cada tupla necesitamos generar permutaciones de sus elementos, ya que solo tienes dos elementos en una tupla, por lo que siempre habrá 4 permutaciones.

Puedes encontrar el algoritmo para generar permutaciones en línea, puedes almacenar cada combinación de permutaciones en tuplas, por lo que la tupla generada arriba en el bucle for generará 4 tuplas

[(0,1), (1,2)] //we created this in for loop

Esto producirá el uso de un algoritmo como este

[(0,0),(0,1),(1,1),(1,0),(1,1),(1,2),(2,1),(2,2)]

Ahora que tienes esta lista, puedes transmitirla fácilmente utilizando la función API de transmisión proporcionada para cada colección.

Editar: Desde, aquíel requisito era producir todos los pares posibles con 2 números, no necesitabas la lógica de combinaciones (no estaba claro con la descripción de la pregunta), simplemente puedes ejecutar dos bucles y producir todas las tuplas necesarias, algo como esto

public class TupelPairs<T> {
    private TupleSet<T> tupleSet;
    private final List<Tuple<T>> tuples;

    public TupelPais(TupleSet<T> tupleSet) {
       this.tupelSet = tupleSet;
       
       // Convert your TupleSet<T> to some list here
       // nums here is the List<T>, as I am not sure what is TupleSet here

       tuples = new ArrayList<>();
       // here we are generating tuple pairs
       for(int i = 0; i < nums.size(); i++) {
           for (T num : nums) {
                tuples.add(new Tuple<T>(nums.get(i), num));
           }
       }
    }

   
    public Stream<Tupel<T>> getElements() {
      return tuples.stream();   // Initialized in constructor 
    }
}

Esto daría un resultado si se supone que se llama con (suponiendo que TupleSet sea algún tipo de conjunto o lista de T y T es un número entero, por ejemplo)

TuplePairs<Integer> pairs = new TuplePairs<Integer>(asList(1,2,3));

pairs.getElements(); // -> [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

1

Gracias por tu consejo con las permutaciones. Estoy seguro de que esta es la solución para mi tarea y busqué muchos ejemplos diferentes.sin embargo, no estoy seguro de cómo ejecutar esto para mi Tuple<T> tipo, ¿podrías explicarnos un poco más cómo llegar allí?

usuario15412162

31 de marzo de 2021 a las 7:30



------------------------------------

Aquí está el código de muestra que resuelve su tarea:

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Set<Tuple<Integer>> tuples = createTuples();

        Set<Integer> allIntegers = tuples.stream()
                .flatMap(integerTuple -> Stream.of(integerTuple.getFirst(), integerTuple.getSecond()))
                .collect(Collectors.toSet());

        List<Tuple> allNumberCombinations = allIntegers.stream()
                .flatMap(firstNumber -> allIntegers.stream().map(secondNumber -> new Tuple<>(firstNumber, secondNumber)))
                .sorted(ascendingComparator())
                .collect(Collectors.toList());

        System.out.println(allNumberCombinations);
    }

    private static Set<Tuple<Integer>> createTuples() {
        return new HashSet<Tuple<Integer>>() {
            {
                add(new Tuple<>(1, 2));
                add(new Tuple<>(3, 2));
            }
        };
    }

    private static Comparator<Tuple<Integer>> ascendingComparator() {
        Comparator<Tuple<Integer>> comparingFirst = Comparator.comparing(Tuple::getFirst);
        Comparator<Tuple<Integer>> comparingSecond = Comparator.comparing(Tuple::getSecond);

        return comparingFirst.thenComparing(comparingSecond);
    }

    @Getter
    @ToString
    @AllArgsConstructor
    @EqualsAndHashCode
    private final static class Tuple<T> {
        private final T first;
        private final T second;
    }
}

El resultado será:

[Main.Tuple(first=1, second=1), Main.Tuple(first=1, second=2), Main.Tuple(first=1, second=3), Main.Tuple(first=2, second=1), Main.Tuple(first=2, second=2), Main.Tuple(first=2, second=3), Main.Tuple(first=3, second=1), Main.Tuple(first=3, second=2), Main.Tuple(first=3, second=3)]

Breve resumen del código proporcionado:

crear tuplas obtener conjunto de todos los números que estaban en tuplas iterar sobre esos números - y para cada número iterar sobre todos los números - para crear todas las combinaciones posibles ordenar las tuplas para que estén en orden ascendente imprimirlos

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare