ACM 数据离散化 Java实现

本文介绍在ACM竞赛中如何通过数据离散化处理优化算法性能,包括数据排序、去重及使用二分查找等关键步骤,提供Java实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在ACM竞赛中可能经常需要对数据进行离散化处理, 通过改变他们的大小,但不改变他们的大小关系,这种做法往往可以节省空间,减低时空复杂度.  为实现数据的离散化, 首先需要对数组进行排序, 如果数据可能出现重复, 则需要对数据进行去重处理, 需要用到unique()函数, 下面是数据离散化的java实现.
/*
 * Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
 * @Author: Ng Kimbing, HNU.
 * @LastModified:2019-04-11 T 13:06:26.985 +08:00
 */
package MyUtil;

import java.util.Arrays;
import java.util.Comparator;

public class Discretization {
    /**
     * Remove consecutive values from a sequence
     *
     * @param a     the array
     * @param first first index.
     * @param last  last index.
     * @return The index designating the end of the resulting sequence.
     */
    public static int unique(int[] a, int first, int last) {
        if (first == last)
            return last;
        int result = first;
        while (++first != last) {
            if (!(a[result] == a[first])) {
                a[++result] = a[first];
            }
        }
        return ++result;
    }

    public static int unique(Object[] a, int first, int last, Comparator<Object> c) {
        if (first == last)
            return last;
        int result = first;
        while (++first != last) {
            if (c.compare(a[result], a[first]) != 0) {
                a[++result] = a[first];
            }
        }
        return ++result;
    }

    /**
     * Finds the first position in which @key could be inserted without changing the ordering.
     *
     * @param array the array
     * @param size  the size of the array.
     * @param key   The search item
     * @return returns the index pointing to the first element <em>not less than</em> {@code key},
     * or {@code size} if every element is less than {@code key}.
     */
    public static int lowerBound(int[] array, int size, int key) {
        int first = 0, middle;
        int half, len;
        len = size;
        //binary search
        while (len > 0) {
            half = len >> 1;
            middle = first + half;
            if (array[middle] < key) {
                first = middle + 1;
                len = len - half - 1;       //search in the right sub-sequence
            } else
                len = half;            //search in the left sub-sequence, middle included.
        }
        return first;
    }

    public static int lowerBound(Object[] array, int size, Object key, Comparator<Object> c) {
        int first = 0, middle;
        int half, len;
        len = size;
        //binary search
        while (len > 0) {
            half = len >> 1;
            middle = first + half;
            if (c.compare(array[middle], key) < 0) {
                first = middle + 1;
                len = len - half - 1;       //search in the right sub-sequence
            } else
                len = half;            //search in the left sub-sequence, middle included.
        }
        return first;
    }

    static int upperBound(int[] array, int size, int key) {
        int first = 0, len = size - 1;
        int half, middle;
        while (len > 0) {
            half = len >> 1;
            middle = first + half;
            if (array[middle] > key)
                len = half;
            else {
                first = middle + 1;
                len = len - half - 1;
            }
        }
        return first;
    }

    /**
     * Discretize the array.
     *
     * @param a the array.
     */
    public static void discretize(int[] a) {
        Arrays.sort(a);
        int newLen = unique(a, 0, a.length);
        for (int i = 0; i < newLen; ++i)
            a[i] = lowerBound(a, newLen, a[i]);
    }

    public static void discretize(int[] a, int length) {
        Arrays.sort(a, 0, length);
        int newLen = unique(a, 0, length);
        for (int i = 0; i < newLen; ++i)
            a[i] = lowerBound(a, newLen, a[i]);
    }

    public static int[] discretizeWithoutChanges(int[] a) {
        int b[] = new int[a.length];
        System.arraycopy(a, 0, b, 0, a.length);
        Arrays.sort(b);
        int newLen = unique(b, 0, b.length);
        int[] ans = new int[newLen];
        for (int i = 0; i < newLen; ++i)
            ans[i] = lowerBound(b, newLen, b[i]);
        return ans;
    }

    public static void main(String[] args) {
        int[] a = {2, 0, 1, 9, 4, 1, 1};
        discretize(a);
        System.out.println(Arrays.toString(a));
        int[] b = {2, 0, 1, 9, 4, 1, 1};
        System.out.println(Arrays.toString(discretizeWithoutChanges(b)));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值