【问题标题】:Print unique subset in lexicographic order按字典顺序打印唯一子集
【发布时间】:2021-06-24 16:26:03
【问题描述】:

对于我的字符串输入“aaa”,我希望答案是

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

我的代码:

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);
        }
    }
}

这段代码给了我这个输出:

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

但我希望这样: 所需输出:

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

我为获取唯一子集而编写的逻辑也可以使用TreeSetHashSet 之类的集合来完成。 我尝试使用TreeSet,答案是排序顺序和唯一子集,但有一些额外的逗号。 如果有人能解决我的两个问题,那将非常有帮助。

【问题讨论】:

    标签: java arrays sorting recursion subset


    【解决方案1】:

    您可以使用 TreeSet,并添加一个custom comparator

    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;
    });
    

    并使用replaceAll("\\s+","") 删除多余的空格。

    所有东西放在一起:

    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);
            }
        }
    }
    

    输出:

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

    或者(已在 cmets 中指出)您可以将 Collections.reverse 与我们的 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);
            }
        }
    

    输出:

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

    【讨论】:

      【解决方案2】:

      解决方法是使用重载方法List#add(int, T),而不是List#add(T)。这样,您的项目将始终插入到列表的开头而不是结尾。

      你可以替换这一行

      big.add(new ArrayList&lt;Character&gt;(temp));

      通过以下方式

      big.add(0, new ArrayList&lt;Character&gt;(temp));

      你会得到以下结果

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

      【讨论】:

        猜你喜欢
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多