分治法-求解众数问题Java

1.众数问题:

给定含有N个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数,多重集合S中重数最大的元素称为多重集合S的众数,众数的重数称为多重集合S的重数,试求一个给定多重结合的重数和众数。

例如:S={a,b,b,b,f,f,4,5}的重数是3,众数是b

2.算法思路:

  • 首先为集合S排序,使之成为有序的数组(使用Arrays类的sort方法)
  • 取中位数为众数,中位数的个数为重数,确定左右界
  • 向左界递归,取中位数为众数,取中位数个数为重数,比较
  • 向右界递归,取中位数为众数,取中位数个数为重数,比较

3.问题:

翻阅网上的代码,多是使用c++实现,而c++代码中有引用参数传递的过程,在程序运行中可以直接引用函数传参,但Java中没有提供。在阅读(7条消息) 分治法-众数问题java实现_cook_1996的博客-CSDN博客 这篇博客后,发现了IntHolder这个类。

IntHolder持有者类型:因为java中只存在值传递,同时包装类一旦创建其数值是不能改变的。所有不可能实现一个方法改变一个数据类型的值。如果想编写一个修改数据值参数的方法,就需要使用在 org.omg.CORBA 包中定义的持有者(holder)类型,包括IntHolder、BooleanHolder等。每个持有者类型都包含一个共有域值,通过它可以访问储存在其中的值。

4.代码:

import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;

public class Mode {

    public static void getMaxCnt(int a[], int n, IntHolder num, IntHolder maxCnt){
        int l =0, r = 0;
        int s;
        int mid = n / 2;
        for( l = 0;l < mid;l ++){
            if(a[l] == a[mid])
                break;
        }
        for(r = mid + 1;r < n;r ++){
            if(a[r] != a[mid])
                break;
        }
        s = r - l;
        if(s > maxCnt.value){
            num.value = a[mid];
            maxCnt.value = s;
        }
        if(s == maxCnt.value){
            if(num.value > a[mid]){
                num.value = a[mid];
                maxCnt.value = s;
            }
        }
        if(l + 1 > maxCnt.value){
            getMaxCnt(a,l+1,num,maxCnt);
        }
        if(n - r > maxCnt.value){
            int [] b = new int[n-r];
            for(int i = 0;i < n-r;i ++){
                b[i] = a[r + i];
            }
            getMaxCnt(b,n-r,num,maxCnt);
        }

    }

    public static void main(String[] args) {
        int i,n;

        IntHolder num = new IntHolder();
         IntHolder maxCnt = new IntHolder();
        System.out.println("请输入数组个数:");
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        int []a = new int[n];
        System.out.println("请输入一个数组:");
        for(i = 0;i < n;i ++){
            a[i] = scanner.nextInt();
        }
        Arrays.sort(a);
        getMaxCnt(a,n,num,maxCnt);
        System.out.println("众数:" + num.value + " 重数:" + maxCnt.value);
    }
}

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值