Find the modal value of an integear array.
Hey, i am just making a simple programme to understand to use methods as this is my first programming language i am learning its sometimes a little difficult but i thought i had it. But just cant quite think of how to get the most frequent value.
I now was thinking i could use the
.sort()
function but i am still unsure where to go after that.
Any suggestions would be great.
a sample array which i would want to find the modal value of would be:
int a[] ={1, 17, 6, 4, 5, 5, 6, 4 , 2 , 2 , 2 , 2};
Thanks
[642 byte] By [
RedBraina] at [2007-10-3 11:32:45]

How would you do it with pencil and paper?
You could do it with an iteration after sorting, checking for value changes and counting how often one value appears, and storing that value at the same time. Needs a little fiddling with variables, though.
Alternately, you could just once iterate over the unsorted array, and use a Hashmap, with the numbers as keys: if a key is already inside, increase the counter you store as its value. Otherwise, add the number and a counter with the value of 1.
If you use 1.5, autoboxing should make this quite convenient.
Hi,
It's a bit tricky. What you could do is:
for each value
look in a map and see if the value exists as key
if it does, get the counter for the key (the counter is the value in the map), and increase it
if it doesn't, create a new counter, and put it in the map
when done get all values from the map, and look for the highest value. The counter should also contain which value it is a counter for.
Kaj
kajbja at 2007-7-15 13:59:36 >

Hi,
1st of all left your 5 dukes for later when You will ask harder questions :-))
2nd-ly:
When you would like to use sort and count the array try something like this
import java.util.Arrays;
public class ArraySample {
public static void main(String[] args) {
int a[] = {1, 17, 6, 4, 5, 5, 6, 4 , 2 , 2 , 2 , 2};
// This will be our result
int maxCount = -1;
int maxNumber = -1;
// We use this to keep track on current group of numbers
int currentCount = -1;
int currentNumber = -1;
// Sorty first -- array given by referce is sorted (nothing returned!)
Arrays.sort(a);
// Let's walk sorted array and count
for(int index = a.length - 1; index >= 0; index--) {
// Let's test if we are still counting same group of number e.g. '3'
if (a[index] != currentNumber) {
// If not let's look if this isn't by any chance the largest group
if (maxCount < currentCount) {
// Yes! Store information about it
maxCount = currentCount;
maxNumber = currentNumber;
}
// Store information about new group of numbers we accountered
currentNumber = a[index];
currentCount = 0;// reset counter
}
currentCount++;
}
// Finished, just print result stored in maxNumber
System.out.println( "Modal value is " + String.valueOf(maxNumber) +
" occured "+String.valueOf(maxCount)+" time(s)" );
}
}
Note that there are also another possibilities, but they involve few different Java classes (collection classes) -- I don't know how proficient with Java are you now, so IMHO this simple solution based on Your idea of sort and count would be enaough.
Message was edited by:
a3cchan
Word on complexity for both principles (sorting vs using collections to count size):
For sorting it's simple:
(1 + log(n) ) * n -- n*log(n) {for sort} + n {for walking the array} (assuming that sort complexity is around n*log(n) )
For collections it may be around:
2 * n * log(n) -- slightly better
I think it's like:
n {for walking array} * ( log(n) {key lookup} + log(n) {key insert} )
> int a[] = {-1, -1, 0, 1 , 2 }; Modal value is 2 occured 1 time(s)Doesn't seem correct. :)
Ok, I assumed only positive numbers. Slighly better (and i think sufficient) solution is using Integer.MIN_VALUE instead of each -1.
Correct example can use flag to determine initial loop (firstLoop)
import java.util.Arrays;
public class ArraySample {
public static void main(String[] args) {
// Targeted array
int a[] = {1, 17, 6, 4, 5, 5, 6, 4 , 2 , 2 , 2 , 2};
// Test array size
if (a == null || a.length == 0) {
// Empty => noting to do
System.out.println("Array is empty.");
System.exit(-1);
}
// This will be our result
int maxCount = Integer.MIN_VALUE;
int maxNumber = Integer.MIN_VALUE;
// We use this to keep track on current group of numbers
int currentCount = Integer.MIN_VALUE;
int currentNumber = Integer.MIN_VALUE;
// This is used to skip first test
boolean firstLoop = true;
// Sorty first -- array given by referce is sorted (nothing returned!)
Arrays.sort(a);
// Let's walk sorted array and count
for(int index = a.length - 1; index >= 0; index--) {
// Let's test if we are still counting same group of number e.g. '3'
if (firstLoop || a[index] != currentNumber) {
// If not let's look if this isn't by any chance the largest group
if (maxCount < currentCount) {
// Yes! Store information about it
maxCount = currentCount;
maxNumber = currentNumber;
}
// Store information about new group of numbers we accounted
currentNumber = a[index];
currentCount = 0;// reset counter
firstLoop = false;
}
currentCount++;
}
// Finished, just print result stored in maxNumber
System.out.println( "Modal value is " + String.valueOf(maxNumber) +
" occured "+String.valueOf(maxCount)+" time(s)" );
}
}
CeciNEstPasUnProgrammeur> do not behave like kid, pls :-P It was just answer on "learning Java" question. Be supportive :-P
> CeciNEstPasUnProgrammeur> do not behave like kid, pls
He was not acting like a kid. You are now.
> :-P It was just answer on "learning Java" question.
And he corrected a mistake of which you, and the OP, can learn something perhaps.
> Be supportive :-P
He was.
Ok. I am sorry CeciNEstPasUnProgrammeur :-( But it was no mistake -- just attempt to make things simple :-(
> But it was no mistake -- just attempt to make things> simple :-(I find it simpler to use a MapKaj
kajbja at 2007-7-15 13:59:36 >

Wo thanks i will just take a while for me to properly understand that because we havent done that muhc programming over all i think my biggest problem is i havent had enough practice with arrays. ah well Thanks i have another question tho, with methods.
This is a small extract of a programme which i am making and i am unsure on how to make the method work this like.
public class Marks
{
public static int[] enterMarks()
{
int[] classMarks = new int[20];
System.out.println("Please enter 20 makes, between 0 and 20: ");
for(int i=0; i<classMarks.length; i++)
{
classMarks[i] = getScannerInput.anInt("Mark " + (i+1) + "= ");
while((classMarks[i] < 0) || (classMarks[i] > 20))//check to make sure the marks are between 0 and 20
{
System.out.println("That is an invalid mark, please try again.");
classMarks[i] = getScannerInput.anInt("Mark " + (i+1) + ": ");
}
}
for(int k=0; k><classMarks.length; k++)
System.out.print(classMarks[k] + ", ");
return classMarks;
}
public static void main(String[] args)
{
int[] Marks = enterMarks();
}
}
I can make it work if i make classMarks a global array but i want to make it work like that.>
> Ok. I am sorry CeciNEstPasUnProgrammeur :-(
> But it was no mistake -- just attempt to make things
> simple :-(
And I was just trying to make sure you didn't make it simpler than it is. Using magic numbers as flags if you can get random input is no good idea.
No worries.
:
:
public static void main(String[] args){
int[] marks = enterMarks();
find(marks);
}
public static void find(int[] marks) {
// Do something fun here
}
kajbja at 2007-7-15 13:59:36 >

@OP: with marks it's actually easier to simply have an array of ints. The length is the number of possible marks you can get (like 5) and the value is the number of occurance. Like:
for (int i = 0; i < grades.length; i++) {
int currentGrade = grades[i];
marksMap[currentGrade -1]++;
}
And in the end simply find the highest value in marksMap.
> And I was just trying to make sure you didn't make it
> simpler than it is. Using magic numbers as flags if
> you can get random input is no good idea.
Ok, I confess that using -1 was quite a stupid idea -- minus one is dangerous number :-) Maybe just maybe Integer.MIN_VALUE. Third option, equal to boolean flag, is using Integer class and null. But code w/o autoboxing, mentioned by CeciNEstPasUnProgrammeur, looks nasty.
> 1st of all left your 5 dukes for later when You will
> ask harder questions :-))
Btw. There's no reason to save your dukes. You will never run out of dukes.
http://developers.sun.com/forums/dukestars.jsp
"Are your Duke Stars getting low? Now, forum users with a balance of 15 Duke Stars or less will automatically be granted 25 additional Duke Stars."
Kaj
kajbja at 2007-7-15 13:59:36 >

> "Are your Duke Stars getting low? Now, forum users> with a balance of 15 Duke Stars or less will> automatically be granted 25 additional Duke Stars."Great. Inflation.