Reputation: 18875
The question goes:
Write a method called mode that returns the most frequently occurring element of an array of integers. Assume that the array has at least one element and that every element in the array has a value between 0 and 100 inclusive. Break ties by choosing the lower value.
For example, if the array passed contains the values {27, 15, 15, 11, 27}, your method should return 15. (Hint: You may wish to look at the Tally program from earlier in this chapter to get an idea of how to solve this problem.)
Below is my code that almost works except for single-element arrays
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;
}
Edit: finally figured it out. Changed count1 = 0;
to count1 = 1;
everything works now!
Upvotes: 16
Views: 133987
Reputation: 1
import java.util.HashMap;
public class 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;
}
}
Upvotes: 0
Reputation: 1071
You should use a hashmap for such problems. it will take O(n) time to enter each element into the hashmap and o(1) to retrieve the element. In the given code, I am basically taking a global max and comparing it with the value received on 'get' from the hashmap, each time I am entering an element into it, have a look:
hashmap has two parts, one is the key, the second is the value when you do a get operation on the key, its value is returned.
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;
}
Upvotes: 13
Reputation: 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];
}
}
Upvotes: 0
Reputation: 435
Here, I have coded using single loop. We are getting mode from a[j-1] because localCount was recently updated when j was j-1. Also N is size of the array & counts are initialized to 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];
}
}
Upvotes: 0
Reputation: 1
This is not the most fastest method around the block, but is fairly simple to understand if you don't wanna involve yourself in HashMaps and also want to avoid using 2 for loops for complexity issues....
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;
}
Upvotes: 0
Reputation: 313
Based on the answer from @codemania23 and the Java Docs for HashMap I wrote this code snipped and tests of a method that returns the most occurrent number in an array of numbers.
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;
}
}
Unit Tests
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));
}
}
Upvotes: 0
Reputation: 1
I have recently made a program that computes a few different stats, including mode. While the coding may be rudimentary, it works for any array of ints, and could be modified to be doubles, floats, etc. The modification to the array is based on deleting indexes in the array that are not the final mode value(s). This allows you to show all modes (if there are multiple) as well as have the amount of occurrences (last item in modes array). The code below is the getMode method as well as the deleteValueIndex method needed to run this code
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;
}
Upvotes: 0
Reputation: 121
I know that this question is from a while ago, but I wanted to add an answer that I believe expands upon the original question. The addendum to this question was to write the mode method without relying upon a preset range (in this case, 0 through 100). I have written a version for mode that uses the range of values in the original array to generate the count array.
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
}
Upvotes: 0
Reputation: 21
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;
}
Upvotes: 2
Reputation:
Here is my answer.
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;
}
Upvotes: 0
Reputation: 11
THIS CODE CALCULATES MODE, MEDIAN, AND MEAN. IT IS TESTED AND IT DOES WORK. It is a complete program from start to finish and will compile.
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();
}
}
Upvotes: -2
Reputation: 5425
I would use this code. It includes an instancesOf
function, and it runs through each number.
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}));
}
}
I noticed that the code Gubatron posted doesn't work on my computer; it gave me an ArrayIndexOutOfBoundsException
.
Upvotes: 0
Reputation: 53
check this.. Brief:Pick each element of array and compare it with all elements of the array, weather it is equal to the picked on or not.
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.
Upvotes: 1
Reputation: 6479
You should be able to do this in N operations, meaning in just one pass, O(n) time.
Use a map or int[] (if the problem is only for ints) to increment the counters, and also use a variable that keeps the key which has the max count seen. Everytime you increment a counter, ask what the value is and compare it to the key you used last, if the value is bigger update the key.
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));
}
}
Upvotes: 3