对多个结果和参数互相嵌套的式子进行排序

正文

对多个结果和参数互相嵌套的式子进行排序

目的:式子按顺序执行一次,得到所有的结果


import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 对多个结果和参数互相嵌套的式子进行排序
 * 目的:式子按顺序执行一次,得到所有的结果
 * 模拟数据格式:
 * ["f_2268", "cal(f_2307+f_2276)"]
 * ["f_2274", "cal(f_2247-f_2268)"]
 * ["f_2276", "sum(f_2262)"]
 */
public class SortTest {
    public static void main(String[] args) {
        // 开始时间
        long start = System.currentTimeMillis();
        /**
         * 模拟提取所有式子结果,存入一个集合中的行为
         * 此时,集合中的元素是乱序的
         * 预想:最终将集合里的元素可以按照正确的顺序排列
         */
        List<String> sortedList = new ArrayList<String>() {{
//            add("f_2268");
//            add("f_2274");
//            add("f_2276");
//            add("公式1");
//            add("公式2");
//            add("公式3");
//            add("公式4");
            add("z");
            add("f");
            add("zz");
            add("b");
            add("g");
            add("a");
            add("d");
            add("e");
            add("c");
        }};
        /**
         *  模拟构建结果和参数的关联关系
         */
        Map<String, List<String>> tempMap = new HashMap<String, List<String>>() {{
//            put("f_2268", Arrays.asList("f_2307", "f_2276"));
//            put("f_2274", Arrays.asList("f_2247", "f_2268"));
//            put("f_2276", Arrays.asList("f_2262"));
//            put("公式3", Arrays.asList("公式2"));
//            put("公式1", Arrays.asList("公式3", "公式4"));
//            put("公式4", Arrays.asList(""));
//            put("公式2", Arrays.asList("公式4"));
            put("z", Arrays.asList("a", "d", "e", "g"));
            put("f", Arrays.asList("b"));
            put("b", Arrays.asList("a"));
            put("g", Arrays.asList("a", "d", "c"));
            put("a", Arrays.asList(""));
            put("d", Arrays.asList("b"));
            put("e", Arrays.asList("a"));
            put("c", Arrays.asList(""));
            put("zz", Arrays.asList("z"));
        }};
        /**
         * 将互相嵌套的式子存入一个集合中,方便后续处理
         */
        Map<String, HashSet<String>> mapping = new HashMap<>();
        for (int i = 0; i < sortedList.size(); i++) {
            HashSet<String> set = new HashSet<>();
            for (int j = 0; j < sortedList.size(); j++) {
                if (j == i) continue;
                if (tempMap.get(sortedList.get(i)).contains(sortedList.get(j))) {
                    set.add(sortedList.get(j));
                }
            }
            mapping.put(sortedList.get(i), set);
        }
        // 取出没有被引用的式子
        List<String> independentList = sortedList.stream().filter(s -> mapping.get(s).size() == 0).collect(Collectors.toList());
        // 取出被引用的式子
        List<String> referencedList = sortedList.stream().filter(s -> mapping.get(s).size() != 0).collect(Collectors.toList());
//        List<String> newSortedList = new ArrayList<>();
//        newSortedList.addAll(independentList);
//        newSortedList.addAll(referencedList);
        // 将两个集合合并,没有被引用的式子在前,被引用的式子在后
        // 减少循环次数
        List<String> newSortedList = Stream.of(independentList, referencedList).flatMap(Collection::stream).collect(Collectors.toList());
        int count = 0;
        // 递归排序
        loop(mapping, newSortedList, count, newSortedList.size());

        System.out.println("===============================================================================");
        System.out.println("最终排序为:");
        newSortedList.forEach(System.out::println);
        System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
    }

    public static BigInteger getFactorial(int num) {
        BigInteger result = BigInteger.ONE;
        for (int i = 1; i <= num; i++)
            result = result.multiply(BigInteger.valueOf(i));
        return result;
    }

    /**
     * 递归排序
     *
     * @param tempMap 结果和参数的关联关系
     * @param newSortedList 最终排序的集合
     * @param count 当前递归次数
     * @param maxCount 最大递归次数,超过则说明存在循环引用的现象,终止递归!
     */
    private static void loop(Map<String, HashSet<String>> tempMap, List<String> newSortedList, int count, int maxCount) {
        count++;
        if (count > maxCount) {
            throw new RuntimeException("操作异常,原因:发现多个计算公式的参数和结果循环引用!");
        }
        System.out.println("===============================================================================");
        System.out.println("开始了第" + count + "次递归");
        // 记录是否需要调换位置的标志
        boolean flag = false;
        for (int i = 0; i < newSortedList.size() - 1; i++) {
            int sort = i + 1;
            System.out.println("///");
            System.out.println("第" + sort + "次循环");
            System.out.println("被比较参数:" + newSortedList.get(i));
            for (int j = i + 1; j < newSortedList.size(); j++) {
                System.out.println("比较参数:" + newSortedList.get(j));
                if (tempMap.get(newSortedList.get(i)).contains(newSortedList.get(j))) {
                    System.out.println("{");
                    System.out.println("\t\t发现需要调换位置的参数:");
                    System.out.println("\t\t前参数:" + newSortedList.get(i));
                    System.out.println("\t\t后参数:" + newSortedList.get(j));
                    System.out.println("}");
                    Collections.swap(newSortedList, i, j);
                    flag = true;
                }
            }
        }
        // 如果存在需要调换位置的参数,则说明元素排列还不稳定,需要再进行一次递归排序
        if (flag) {
            loop(tempMap, newSortedList, count, maxCount);
        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值