zoukankan      html  css  js  c++  java
  • 金条分割+最小堆实现

    金条分割问题:

    采用优先级队列实现的,这里的优先级队列默认按照最小堆生成。所以可以不用定义比较器。等价--如注释

    如果需要大根堆的话,就需要定义比较器。

    package day5;
    
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.PriorityQueue;
    
    
    /*
     * 一块金条切两块,需要花费和长度数值一样的铜板。怎么分最省铜板。
     * eg:    给定数组{10,20,30}代表三个人,整块金条长度就是10+20+30=60,
     *         分成数组中的10,20,30三个部分。最优解是先分30+40 再分10+20共需90个铜板
     * 
     * 实质是哈夫曼编码,每次取出两个最小的相加相加放回数组,依次进行到数组元素只剩下一个
     * 此时就是最小代价
     * 
     * 知道但是不会编码,就很尬了
     * 
     * !!!!!!!知识点:!!!!!!!!!!!
     * 这种在数组中取最大、最小再放回的,考虑堆结构。
     * 当总和可以表示成分的和或者乘的时候,考虑哈弗曼编码
     * 
     */
    public class Code03_GoldBarSegmentation {
    
        public static void main(String[] args) {
            int arr[] = {10,20,30};
            System.out.println(Hoffmann(arr ));
        }
    
    
        public static class minHeapComparator implements Comparator<Integer>{
    
            @Override
            public int compare(Integer arg0, Integer arg1) {
                return arg0 - arg1;
            }
            
        }
        public static int Hoffmann(int arr []) {
            //PriorityQueue<Integer> minHeap = new PriorityQueue<>();
            PriorityQueue<Integer> minHeap = new PriorityQueue<>(new minHeapComparator());
            for(int i = 0 ; i <arr.length ;i ++) {
                minHeap.add(arr[i]);
            }
            int sum =0;
            while(minHeap.size() >1) {
                int cur = minHeap.poll()+minHeap.poll();
                sum += cur;
                minHeap.add(cur);
            }
            return sum;
        }
        
    
        
    }

    最小堆实现:

      
    
    // 自己堆快忘了,手写一个,复习
    
    // 从小到大排序,需要大根堆实现
    // 从大到小排序,用小根堆实现
    
    /*
    * 小根堆: 
    * hoopinsert:加入一个新节点,调整(向上)
    * heapify:一个数变大之后往下调,往下调,往下调 
    * 1.左右孩子是否存在?
    * 2、找到左右孩子中最小的那个,跟当前节点比较,若小就交换,否在停止 heapSort
    */
    
    public static class MyHeap {        
    
            public static  void swap(int arr[], int i, int j) {
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
    
            public static  void heapify(int arr[], int size, int index) {
                int left = index * 2 + 1;
                while (left < size) {// 保证孩子存在
                    // 保证右孩子存在的情况下
                    int childmin = (left + 1 < size && arr[left + 1] < arr[left]) ? left + 1 : left;
                    childmin = arr[childmin] < arr[index] ? childmin : index;
                    if (childmin == index)
                        break;
                    swap(arr, childmin, index);
                    index = childmin;
                    left = index * 2 + 1;
                }
            }
    
            public static  void hoopinsert(int arr[], int index) {
                int father = (index - 1) / 2;
                while (arr[father] > arr[index]) {
                    swap(arr, father, index);
                    index = father;
                    father = (index - 1) / 2;
                }
            }
    
            public static  void heapSort(int arr[]) {
                if (arr == null || arr.length < 2)
                    return;
                // 建立小根堆
                for (int i = 0; i < arr.length; i++) {
                    hoopinsert(arr, i);
                }
                // 排序,需要从小根堆中每次取堆顶,然后跟最后一个数交换。size-1,重新排一遍。
                //将size = arr.length-1 ,        --size换成--size,跑出来结果是错的。
                //没弄明白
                
                int size = arr.length;
                swap(arr, --size, 0);
                while (size > 0) {
                    heapify(arr, size, 0);
                    swap(arr, --size, 0);
                }
    
            }
    
            // for test
            public static int[] generateRandomArray(int maxSize, int maxValue) {
    
                int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
                for (int i = 0; i < arr.length; i++) {
                    arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
                }
    
                return arr;
            }
    
            public static int[] copyArray(int arr[]) {
                if (arr == null) {
                    return null;
                }
                int[] res = new int[arr.length];
                for (int i = 0; i < arr.length; i++) {
                    res[i] = arr[i];
                }
                return res;
    
            }
    
            public static void print(int arr[]) {
                for (int i = 0; i < arr.length; i++) {
                    System.out.print(arr[i] + " ");
                }
                System.out.println();
    
            }
            
            public static void comparator(int arr[]) {
                Arrays.sort(arr);
                for (int i = 0 ; i <arr.length/2;i ++) {
                    swap(arr,i,arr.length-1-i);
                }
            }
    
            public static boolean isEqual(int arr[], int res[]) {
                if ((arr == null && res != null) || (arr != null && res == null))
                    return false;
                if (arr == null && res == null)
                    return true;
                if (arr.length != res.length)
                    return false;
                for (int i = 0; i < arr.length; i++) {
                    if (arr[i] != res[i])
                        return false;
                }
                return true;
            }
    
            public static void main(String[] args) {
    
                int maxSize = 30;
                int maxValue = 100;
                int testTime = 1000;
                boolean suceed = true;
                //int arr[] = { 6, 12, 3, 8, 4, 1, 2, 9 };
                //heapSort(arr);
                //print(arr);
    
                for (int i = 0; i < testTime; i++) {
                    int[] arr1 = generateRandomArray(maxSize, maxValue);
                    int[] arr2 = copyArray(arr1);
    
                    heapSort(arr1);
                    comparator(arr2);
                    if (!isEqual(arr1, arr2)) {
                        suceed = false;
                        // System.out.println("********************");
                        print(arr1);
                        print(arr2);
                        break;
    
                    }
    
                }
                System.out.println(suceed ? "Nice!" : "Flucking Fucked !");
            }
        }
        
     

    遇到一个问题:

    我本来想将自己写的堆放到金条分隔中使用,于是就直接把  MyHeap类 放进了GoldBarSegmentation类 里面,没写GoldBarSegmentation类 的主函数,运行MyHeap类成功后写了删掉 MyHeap类主函数,写GoldBarSegmentation类 主函数之后提示“找不到或无法加载主类 ”。即后写的主函数不被识别,即使是删掉MyHeap类,用自带的优先级队列也不行。

    方法:

    应该是eclipse在第一运行程序的时候记住了一些东西。通过  菜单栏 ——> run  ——>run Configurations 打开后在左侧找到对应的程序名,右击delect。

    再次重新运行就可以了。

  • 相关阅读:
    ASP.NET MVC案例——————拦截器
    Windows Azure Virtual Network (10) 使用Azure Access Control List(ACL)设置客户端访问权限
    Windows Azure Storage (20) 使用Azure File实现共享文件夹
    Windows Azure HandBook (5) Azure混合云解决方案
    Windows Azure Service Bus (6) 中继(Relay On) 使用VS2013开发Service Bus Relay On
    Azure PowerShell (9) 使用PowerShell导出订阅下所有的Azure VM的Public IP和Private IP
    Windows Azure Service Bus (5) 主题(Topic) 使用VS2013开发Service Bus Topic
    Azure China (9) 在Azure China配置CDN服务
    Windows Azure Storage (19) 再谈Azure Block Blob和Page Blob
    Windows Azure HandBook (4) 分析Windows Azure如何处理Session
  • 原文地址:https://www.cnblogs.com/codinghard/p/11488354.html
Copyright © 2011-2022 走看看