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。

    再次重新运行就可以了。

  • 相关阅读:
    封装好的AFN网络请求框架和MBProgress
    iOS定时器的使用
    iOS去除导航栏和tabbar的1px横线
    移动端加解密
    改变字符串中部分字符传的字体大小和颜色
    关于NSLog
    ipad开发:二维码扫描,摄像头旋转角度问题解决办法
    iOS-图文表并茂,手把手教你GCD
    计算富文本的高度
    jsp打印
  • 原文地址:https://www.cnblogs.com/codinghard/p/11488354.html
Copyright © 2011-2022 走看看