14

问题是:

编写一个名为 mode 的方法,它返回整数数组中出现频率最高的元素。假设数组至少有一个元素,并且数组中的每个元素的值都在 0 到 100 之间。通过选择较低的值来打破平局。

例如,如果传递的数组包含值 {27, 15, 15, 11, 27},您的方法应该返回 15。(提示:您可能希望查看本章前面的 Tally 程序以了解如何解决这个问题呢。)

下面是我的代码,除了单元素数组之外几乎可以工作

public static int mode(int[] n)
{
    Arrays.sort(n);
    
    int count2 = 0;
    int count1 = 0;
    int pupular1 =0;
    int popular2 =0;
    
    
    for (int i = 0; i < n.length; i++)
    {
            pupular1 = n[i];
            count1 = 0;    //see edit
        
        for (int j = i + 1; j < n.length; j++)
        {
            if (pupular1 == n[j]) count1++;
        }
        
        if (count1 > count2)
        {
                popular2 = pupular1;
                count2 = count1;
        }
        
        else if(count1 == count2)
        {
            popular2 = Math.min(popular2, pupular1);
        }
    }
    
    return popular2;
}

编辑:终于想通了。更改count1 = 0;count1 = 1;现在一切正常!

4

14 回答 14

14

对于此类问题,您应该使用哈希图。将每个元素输入 hashmap 需要 O(n) 时间,检索元素需要 o(1) 时间。在给定的代码中,我基本上取了一个全局最大值并将其与从 hashmap 的“get”上接收到的值进行比较,每次我在其中输入一个元素时,看看:

hashmap有两部分,一是key,二是value,当你对key做get操作时,返回它的值。

public static int mode(int []array)
{
    HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
    int max  = 1;
    int temp = 0;

    for(int i = 0; i < array.length; i++) {

        if (hm.get(array[i]) != null) {

            int count = hm.get(array[i]);
            count++;
            hm.put(array[i], count);

            if(count > max) {
                max  = count;
                temp = array[i];
            }
        }

        else 
            hm.put(array[i],1);
    }
    return temp;
}
于 2015-03-31T16:19:53.583 回答
3

您应该能够在 N 次操作中执行此操作,这意味着只需一次 O(n) 时间。

使用 map 或 int[] (如果问题仅针对整数)来增加计数器,并使用一个变量来保留具有最大计数的键。每次增加计数器时,询问值是什么并将其与您上次使用的键进行比较,如果值更大则更新键。

public class Mode {
public static int mode(final int[] n) {
    int maxKey = 0;
    int maxCounts = 0;

    int[] counts = new int[n.length];

    for (int i=0; i < n.length; i++) {
        counts[n[i]]++;
        if (maxCounts < counts[n[i]]) {
            maxCounts = counts[n[i]];
            maxKey = n[i];
        }
    }
    return maxKey;
}

public static void main(String[] args) {
    int[] n = new int[] { 3,7,4,1,3,8,9,3,7,1 };
    System.out.println(mode(n));
}
}
于 2013-03-31T01:38:13.430 回答
2
public int mode(int[] array) {
    int mode = array[0];
    int maxCount = 0;
    for (int i = 0; i < array.length; i++) {
        int value = array[i];
        int count = 1;
        for (int j = 0; j < array.length; j++) {
            if (array[j] == value) count++;
            if (count > maxCount) {
                mode = value;
                maxCount = count;
            }
        }
    }
    return mode;
}
于 2015-06-20T07:26:39.367 回答
1

检查这个.. 简介:选择数组的每个元素并将其与数组的所有元素进行比较,天气它是否等于选择。

  int popularity1 = 0;
  int popularity2 = 0;
  int popularity_item, array_item; //Array contains integer value. Make it String if array contains string value.
  for(int i =0;i<array.length;i++){
      array_item = array[i];
      for(int j =0;j<array.length;j++){
          if(array_item == array[j])
             popularity1 ++;
          {
      if(popularity1 >= popularity2){
          popularity_item = array_item;
          popularity2 = popularity1;
      }
      popularity1 = 0;
  }
  //"popularity_item" contains the most repeted item in an array.
于 2013-03-31T04:11:51.583 回答
0

我会使用这段代码。它包括一个instancesOf函数,它贯穿每个数字。

public class MathFunctions {

public static int mode(final int[] n) {
    int maxKey = 0;
    int maxCounts = 0;

    for (int i : n) {
        if (instancesOf(i, n) > maxCounts) {
            maxCounts = instancesOf(i, n);
            maxKey = i;
        }
    }

    return maxKey;
}

public static int instancesOf(int n, int[] Array) {
    int occurences = 0;
    for (int j : Array) {
        occurences += j == n ? 1 : 0;
    }
    return occurences;
}

public static void main (String[] args) {
    //TODO Auto-generated method stub
    System.out.println(mode(new int[] {100,200,2,300,300,300,500}));
}
}

我注意到 Gubatron 发布的代码在我的计算机上不起作用;它给了我一个ArrayIndexOutOfBoundsException.

于 2014-10-30T13:54:01.867 回答
0

这是我的答案。

public static int mode(int[] arr) {
    int max = 0;
    int maxFreq = 0;

    Arrays.sort(arr);
    max = arr[arr.length-1];

    int[] count = new int[max + 1];

    for (int i = 0; i < arr.length; i++) {
        count[arr[i]]++;
    }

     for (int i = 0; i < count.length; i++) {
        if (count[i] > maxFreq) {
            maxFreq = count[i];
        }
    }

    for (int i = 0; i < count.length; i++) {
        if (count[i] == maxFreq) {
            return i;
        }
    }
    return -1;
}
于 2015-04-09T12:03:45.250 回答
0

我知道这个问题是不久前提出的,但我想添加一个我认为可以扩展原始问题的答案。这个问题的附录是在不依赖预设范围(在本例中为 0 到 100)的情况下编写模式方法。我已经为 mode 编写了一个版本,它使用原始数组中的值范围来生成计数数组。

public static int mode(int[] list) {

    //Initialize max and min value variable as first value of list
    int maxValue = list[0]; 
    int minValue = list[0];

    //Finds maximum and minimum values in list
    for (int i = 1; i < list.length; i++) {
        if (list[i] > maxValue) {
            maxValue = list[i];
        }

        if (list[i] < minValue) {
            minValue = list[i];
        }
    }

    //Initialize count array with (maxValue - minValue + 1) elements  
    int[] count = new int[maxValue - minValue + 1];

    //Tally counts of values from list, store in array count
    for (int i = 0; i < list.length; i++) {
        count[list[i] - minValue]++; //Increment counter index for current value of list[i] - minValue
    }

    //Find max value in count array
    int max = count[0]; //Initialize max variable as first value of count

    for (int i = 1; i < count.length; i++) {
        if (count[i] > max) {
            max = count[i];
        }
    }

    //Find first instance where max occurs in count array
    for (int i = 0; i < count.length; i++) {
        if (count[i] == max) {
            return i + minValue; //Returns index of count adjusted for min/max list values - this is the mode value in list
        }
    }
    return -1; //Only here to force compilation, never actually used
}
于 2016-03-05T19:53:54.060 回答
0

我最近做了一个程序,可以计算一些不同的统计数据,包括模式。虽然编码可能是初级的,但它适用于任何整数数组,并且可以修改为双精度、浮点数等。对数组的修改是基于删除数组中不是最终模式值的索引. 这允许您显示所有模式(如果有多个)以及出现的数量(模式数组中的最后一项)。下面的代码是运行此代码所需的 getMode 方法以及 deleteValueIndex 方法

import java.io.File;
import java.util.Scanner;
import java.io.PrintStream;

public static int[] getMode(final int[] array) {           
  int[] numOfVals = new int[array.length];
  int[] valsList = new int[array.length];

  //initialize the numOfVals and valsList

  for(int ix = 0; ix < array.length; ix++) {
     valsList[ix] = array[ix];
  }

  for(int ix = 0; ix < numOfVals.length; ix++) {
     numOfVals[ix] = 1;
  }

  //freq table of items in valsList

  for(int ix = 0; ix < valsList.length - 1; ix++) {
     for(int ix2 = ix + 1; ix2 < valsList.length; ix2++) {
        if(valsList[ix2] == valsList[ix]) {
           numOfVals[ix] += 1;
        }
     }
  }

  //deletes index from valsList and numOfVals if a duplicate is found in valsList

  for(int ix = 0; ix < valsList.length - 1; ix++) {   
     for(int ix2 = ix + 1; ix2 < valsList.length; ix2++) {
        if(valsList[ix2] == valsList[ix]) {
           valsList = deleteValIndex(valsList, ix2);
           numOfVals = deleteValIndex(numOfVals, ix2);
        }
     }
  }

  //finds the highest occurence in numOfVals and sets it to most

  int most = 0;

  for(int ix = 0; ix < valsList.length; ix++) {
     if(numOfVals[ix] > most) {
        most = numOfVals[ix];
     }
  }

  //deletes index from valsList and numOfVals if corresponding index in numOfVals is less than most

  for(int ix = 0; ix < numOfVals.length; ix++) {
     if(numOfVals[ix] < most) {
        valsList = deleteValIndex(valsList, ix);
        numOfVals = deleteValIndex(numOfVals, ix);
        ix--;
     }
  }

  //sets modes equal to valsList, with the last index being most(the highest occurence)

  int[] modes = new int[valsList.length + 1];

  for(int ix = 0; ix < valsList.length; ix++) {
     modes[ix] = valsList[ix];
  }

  modes[modes.length - 1] = most;

  return modes;

}

public static int[] deleteValIndex(int[] array, final int index) {   
  int[] temp = new int[array.length - 1];
  int tempix = 0;

  //checks if index is in array

  if(index >= array.length) {
     System.out.println("I'm sorry, there are not that many items in this list.");
     return array;
  }

  //deletes index if in array

  for(int ix = 0; ix < array.length; ix++) {
     if(ix != index) {
        temp[tempix] = array[ix];
        tempix++;
     }
  }
  return temp;
}
于 2016-11-15T05:24:23.617 回答
0

根据@codemania23 的回答和HashMap 的 Java 文档,我编写了这段代码,并测试了一个返回数字数组中出现次数最多的数字的方法。

import java.util.HashMap;

public class Example {

    public int mostOcurrentNumber(int[] array) {
        HashMap<Integer, Integer> map = new HashMap<>();
        int result = -1, max = 1;
        for (int arrayItem : array) {
            if (map.putIfAbsent(arrayItem, 1) != null) {
                int count = map.get(arrayItem) + 1;
                map.put(arrayItem, count);
                if (count > max) {
                    max = count;
                    result = arrayItem;
                }
            }
        }

        return result;
    }
}

单元测试

import org.junit.Test;

import static junit.framework.Assert.assertEquals;

public class ExampleTest extends Example {

    @Test
    public void returnMinusOneWhenInputArrayIsEmpty() throws Exception {
        int[] array = new int[0];
        assertEquals(mostOcurrentNumber(array), -1);
    }

    @Test
    public void returnMinusOneWhenElementsUnique() {
        int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        assertEquals(-1, mostOcurrentNumber(array));
    }

    @Test
    public void returnOne() throws Exception {
        int[] array = new int[]{0, 1, 0, 0, 1, 1, 1};
        assertEquals(1, mostOcurrentNumber(array));
    }

    @Test
    public void returnFirstMostOcurrentNumber() throws Exception {
        int[] array = new int[]{0, 1, 0, 1, 0, 0, 1, 1};
        assertEquals(0, mostOcurrentNumber(array));
    }
}
于 2017-05-06T00:05:33.253 回答
0

这不是该块中最快的方法,但是如果您不想让自己参与 HashMaps 并且还想避免使用 2 个 for 循环来解决复杂性问题,这很容易理解......

    int mode(int n, int[] ar) {
    int personalMax=1,totalMax=0,maxNum=0;

    for(int i=0;i<n-1;i++)
    {

        if(ar[i]==ar[i+1])
        {
            personalMax++;

            if(totalMax<personalMax)
            {
                totalMax=personalMax;
                maxNum=ar[i];
            }
        }    
        else
        {
            personalMax=1;
        }
    }
    return maxNum;
}
于 2017-07-18T23:05:51.143 回答
0

在这里,我使用单循环编码。我们从 a[j-1] 获取模式,因为 localCount 最近在 j 为 j-1 时更新。N也是数组的大小&计数被初始化为0。

        //After sorting the array 
        i = 0,j=0;
        while(i!=N && j!=N){
            if(ar[i] == ar[j]){
                localCount++;
                j++;
            }
            else{
                i++;
                localCount = 0;
            }
            if(localCount > globalCount){
                globalCount = localCount;
                mode = ar[j-1]; 
            }
        }
于 2017-07-20T05:27:50.583 回答
0
    Arrays.sort(arr);
    int max=0,mode=0,count=0;
    for(int i=0;i<N;i=i+count) {
        count = 1;
        for(int j=i+1; j<N; j++) {
            if(arr[i] == arr[j])
                count++;
        }
        if(count>max) {
            max=count;
            mode = arr[i];
        }
    }
于 2017-08-27T09:44:19.493 回答
0

导入 java.util.HashMap;

公共类 SmallestHighestRepeatedNumber { static int arr[] = { 9, 4, 5, 9, 2, 9, 1, 2, 8, 1, 1, 7, 7 };

public static void main(String[] args) {
    int mode = mode(arr);
    System.out.println(mode);
}

public static int mode(int[] array) {
    HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
    int max = 1;
    int temp = 0;

    for (int i = 0; i < array.length; i++) {

        if (hm.get(array[i]) != null) {

            int count = hm.get(array[i]);
            count++;
            hm.put(array[i], count);

            if (count > max || temp > array[i] && count == max) {
                temp = array[i];
                max = count;
            }
        } else
            hm.put(array[i], 1);
    }
    return temp;
}

}

于 2018-07-06T14:52:03.480 回答
-2

此代码计算众数、中位数和均值。它经过测试并且确实有效。它是一个从头到尾的完整程序,并且会编译。

import java.util.Arrays;
import java.util.Random;
import java.math.*;
/**
 *
 * @author Mason
 */
public class MODE{

    public static void main(String args[])
    {
        System.out.print("Enter the quantity of random numbers  ===>>  ");
        int listSize = Expo.enterInt();
        System.out.println();
        ArrayStats intStats = new ArrayStats(listSize);
        intStats.randomize();
        intStats.computeMean();
        intStats.computeMedian();
        intStats.computeMode();
        intStats.displayStats();
        System.out.println();
    }
}


class ArrayStats
{

    private int list[];
    private int size;
    private double mean;        
    private double median;      
    private int mode;           

    public ArrayStats(int s)//initializes class object
    {
        size = s;
        list = new int[size];
    }

    public void randomize()
    {
        //This will provide same numbers every time... If you want to randomize this, you can
        Random rand = new Random(555);
        for (int k = 0; k < size; k++)
            list[k] = rand.nextInt(11) + 10;  
    }

    public void computeMean()
    {
               double accumulator=0;
               for (int index=0;index<size;index++)
               accumulator+= list[index];

               mean = accumulator/size;
    }

        public void computeMedian()
{
        Arrays.sort(list);
                if((size%2!=0))
                    median = list[((size-1)/2)];
                else if(size!=1&&size%2==0)
                {
                    double a =(size)/2-0.5;
                    int a2 =  (int)Math.ceil(a);
                    double b =(size)/2-0.5;
                    int b2 = (int)Math.floor(b);
                    median = (double)(list[a2]+list[b2])/2;
                }
                else if (size ==1)
                    median = list[0];
        }

    public void computeMode()
    {
 int popularity1 = 0;
  int popularity2 = 0;
  int array_item; //Array contains integer value. Make it String if array contains string value.
  for(int i =0;i<list.length;i++){
      array_item = list[i];
      for(int j =0;j<list.length;j++){
          if(array_item == list[j])
             popularity1 ++;
      }
      if(popularity1 >= popularity2){
          mode = array_item;
          popularity2 = popularity1;
      }


      popularity1 = 0;
  }}

    public void displayStats()
    {
        System.out.println(Arrays.toString(list));
        System.out.println();
        System.out.println("Mean: " + mean);
        System.out.println("Median: " + median);
        System.out.println("Mode: " + mode);
        System.out.println();
    }

}
于 2015-02-05T18:50:02.000 回答