Напишите метод mode в Java, чтобы найти наиболее часто встречающийся элемент в массиве

на вопрос:

напишите метод 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; to count1 = 1; все работает теперь!

14 ответов


вы должны использовать HashMap для таких проблем. потребуется время O(n) для ввода каждого элемента в hashmap и o(1) для извлечения элемента. В данном коде я в основном беру глобальный max и сравниваю его со значением, полученным на "get" из hashmap, каждый раз, когда я вхожу в него элемент, смотрите:

hashmap имеет две части, одна-ключ, вторая-значение, когда вы выполняете операцию 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;
}

вы должны быть в состоянии сделать это в N операциях, то есть всего за один проход, O(n) раз.

используйте map или int [] (если проблема только для ints) для увеличения счетчиков, а также используйте переменную, которая держит ключ, который имеет максимальное количество. Каждый раз, когда вы увеличиваете счетчик, спросите, какое значение и сравните его с ключом, который вы использовали последним, если значение больше, обновите ключ.

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));
}
}

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;
}

проверить это.. Кратко: Выберите каждый элемент массива и сравните его со всеми элементами массива, погода равна выбранному или нет.

  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.

Я бы использовал этот код. Он включает в себя


вот мой ответ.

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;
}

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
}

недавно я сделал программу, которая вычисляет несколько различных характеристик, включая режим. Хотя кодирование может быть рудиментарным, оно работает для любого массива интов и может быть изменено на двойники, поплавки и т. д. Модификация массива основана на удалении индексов в массиве, которые не являются конечными значениями режима. Это позволяет отображать все режимы (если их несколько), а также иметь количество вхождений (последний элемент в массиве режимов). Код ниже-это метод 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;
}

на основе ответа от @codemania23 и Java Docs для HashMap Я написал этот код обрезан и тестирует метод, который возвращает наибольшее число вхождений в массиве чисел.

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));
    }
}

Это не самый быстрый метод вокруг блока, но довольно просто понять, если вы не хотите вовлекать себя в хэш-карты, а также хотите избежать использования 2 для циклов для проблем сложности....

    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;
}

здесь я закодировал с помощью одного цикла. Мы получаем режим от[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]; 
            }
        }

    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];
        }
    }

импорт java.утиль.Этого HashMap;

открытый класс SmallestHighestRepeatedNumber { статический 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;
}

}


ЭТОТ КОД ВЫЧИСЛЯЕТ РЕЖИМ, МЕДИАНУ И СРЕДНЕЕ ЗНАЧЕНИЕ. ОН ТЕСТИРУЕТСЯ И РАБОТАЕТ. Это полная программа, от начала до конца и будет компилироваться.

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();
    }

}