Напишите метод 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();
}
}