java: imprime un subconjunto único en orden lexicográfico

CorePress2024-01-25  9

Para mi entrada de cadena "aaa" Quiero que la respuesta sea

[[],[a],[a,a],[a,a,a]]

Mi código:

import java.util.*;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        String a = "aaa";

        char arr[] = a.toCharArray();
        Arrays.sort(arr);
        List<List<Character>> big = new ArrayList<List<Character>>();

        subset(arr, 0, big, new ArrayList<Character>(), true);

        System.out.println(big);
    }

    static void subset(char arr[], int count, List<List<Character>> big,
                       List<Character> temp, boolean flag) {
        if (count == arr.length) {
            big.add(new ArrayList<Character>(temp));
            return;
        }
        if (flag == false && arr[count] == arr[count - 1]) {
            // logic for unique subset
            subset(arr, count + 1, big, temp, false);     
        } else {
            temp.add(arr[count]);
            subset(arr, count + 1, big, temp, true);
            temp.remove(temp.size() - 1);
            subset(arr, count + 1, big, temp, false);
        }
    }
}

Este código me dio este resultado:

[[a, a, a], [a, a], [a], []]

pero quiero esto como: Salida requerida:

[[],[a],[a,a],[a,a,a]]

Además, la lógica que escribí para obtener un subconjunto único también se puede realizar usando una colección como TreeSet y HashSet. Intenté usar TreeSet y la respuesta estaba ordenada y en un subconjunto único, pero con algunas comas adicionales. Sería de gran ayuda si alguien pudiera resolver mis dos problemas.



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

Puedes usar TreeSet y agregar un comparador personalizado:

Set<List<Character>> big = new TreeSet<>((l1, l2) -> {
    if (l1.size() != l2.size()) {
        return l1.size() - l2.size();
    }
    for (int i = 0; i < l1.size(); i++) {
        int strCmp = l1.get(i).compareTo(l2.get(i));
        if (strCmp != 0) {
            return strCmp;
        }
    }
    return 0;
});

Y use reemplazarTodo("\\s+","") para eliminar los espacios adicionales.

Todo junto:

import java.util.*;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        String a = "aaa";
        char[] arr = a.toCharArray();
        Arrays.sort(arr);
        Set<List<Character>> big = new TreeSet<>((l1, l2) -> {
            if (l1.size() != l2.size()) {
                return l1.size() - l2.size();
            }
            for (int i = 0; i < l1.size(); i++) {
                int strCmp = l1.get(i).compareTo(l2.get(i));
                if (strCmp != 0) {
                    return strCmp;
                }
            }
            return 0;
        });

        subset(arr, 0, big, new ArrayList<Character>(), true);
        custom_printing(big);
    }

    public static void custom_printing(Set<List<Character>> big){
        System.out.println(big.toString().replaceAll("\s+",""));
    }

    static void subset(char[] arr, int count, Set<List<Character>> big, List<Character> temp, boolean flag) {
        if (count == arr.length) {
            big.add(new ArrayList<>(temp));
        }
        else if (!flag && arr[count] == arr[count - 1]) {
            // logic for unique subset
            subset(arr, count + 1, big, temp, false);
        } else {
            temp.add(arr[count]);
            subset(arr, count + 1, big, temp, true);
            temp.remove(temp.size() - 1);
            subset(arr, count + 1, big, temp, false);
        }
    }
}

Salida:

[[],[a],[a,a],[a,a,a]]

O (como señaló en los comentarios) puedes usar Collections.reverse combinado con nuestro método custom_printing:

public class Main {
    public static void main(String[] args) {
        String a = "aaa";

        char[] arr = a.toCharArray();
        Arrays.sort(arr);
        List<List<Character>> big = new ArrayList<>();

        subset(arr, 0, big, new ArrayList<>(), true);
        Collections.reverse(big);
        custom_printing(big);
    }

    public static void custom_printing(List<List<Character>> big){
        System.out.println(big.toString().replaceAll("\s+",""));
    }

    static void subset(char[] arr, int count, List<List<Character>> big,
                       List<Character> temp, boolean flag) {
        if (count == arr.length) {
            big.add(new ArrayList<Character>(temp));
            return;
        }
        if (!flag && arr[count] == arr[count - 1]) {
            // logic for unique subset
            subset(arr, count + 1, big, temp, false);
        } else {
            temp.add(arr[count]);
            subset(arr, count + 1, big, temp, true);
            temp.remove(temp.size() - 1);
            subset(arr, count + 1, big, temp, false);
        }
    }

Salida:

[[],[a],[a,a],[a,a,a]]



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

La solución es utilizar el método sobrecargado List#add(int, T) en lugar de List#add(T). De esa manera, tus elementos siempre se insertarán al principio de la lista en lugar del final.

Puedes reemplazar esta línea

big.add(new ArrayList<Carácter>(temp));

Por lo siguiente

big.add(0, nueva ArrayList<Carácter>(temperatura));

Y obtendrás el siguiente resultado

[[], [a], [a, a], [a, a, a]]

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