Finding frequency of most frequent element inside an array - java

I have an array:
int[] anArray = new int[6];
What if the array contained 1,4,5,4,4? How can I get the most matches? In this case 4 is the most frequent number, and there are three of them, so the function should return 3.
Or if I have 1,2,1,2,3 it should return 2.
Or if I have 4,0,1,2,3 it should return 1.
I really can't figure it out. I tried this:
public static int getCorrectMatches(int[] flowers) throws Exception {
int highest = 0;
for(int index = 0; index < 5; index++) {
int count = countMatches(flowers, index);
if(count > highest) {
highest = index;
}
}
return highest;
}
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(; count < array.length && array[count] == match; count++);
return count;
}
Which didn't work. I'd appreciate any help.

Iterate over the array and for each number store a counter in a hashmap where the key of the map is the number and the value is the counter that tracks the number of occurrences. The first time you encounter a new number (for which there is no key) you'll need insert a new counter. The next time you encounter that same number you simply update the existing counter with a new number.
It also wouldn't be too hard to keep a running 'most matches' number and update it each time you are updating a counter.

public static int numberOfMatches(int[] numbers) {
int mostMatches = 0;
for(int i = 0; i < numbers.length; i++) {
int matches = 0;
int holder = numbers[i];
for(int number : numbers) {
if(number == holder) {
matches++;
}
}
if(matches > mostMatches)
mostMatches = matches;
}
return mostMatches;
}
This accepts an array. It checks the length of the array, and loops for each slot.
For each slot, I create 2 variables. holder grabs the value in the slot, and we increase matches any time there is a match.
Once all possible matches have been found for that slot, it compares the amount of matches found to the highest amount of matches found so far.

for each index in array
HashMap.put(number on index i, occurrences) +=1
check biggest value in the hash map
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put(K,%20V)

Your countMatches() method is incorrect. Decouple count from the loop variable and check the equality inside the loop, instead of putting it in the loop condition. Change it to something like this:
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(int i=0; i< array.length ; i++){
if(array[i] == match) count++;
}
return count;
}
Also, if I were you, I'd change
for(int index = 0; index < 5; index++) {
to,
for(int index = 0; index < flowers.length; index++) {

Related

[java]Longest consecutive integers sequence, debug

I have wrote a method for the question:
input: an array of integers
return: the length of longest consecutive integer sequence.
like: for {9,1,2,3}, return 3, cuz{1,2,3}
the method doesnt run well. hope someone could help me with debugging.
public int solution(int[] arr){
int counter = 1;
int max = arr[1];
//find the max in the array
for (int i : arr){
if (i > max){
max = i;
}
}
int[] nArr = new int[max];
for (int i : arr){
nArr[i] = i;
}
List<Integer> counters = new ArrayList<>();
for (int i = 0; i < max; i++){
if (nArr[i] == nArr[i+1] - 1){
counter++;
}else{
counters.add(counter);
counter = 1;
}
}
max = counters.get(1);
for (int i : counters){
if (i > max){
max = i;
}
}
return max; }
thanks a lot!!!
You dont need to use ArrayList... If all you want is max count of sequential integers, then try this:
int[] a = somethingBlaBla;
int counter = 0; // Stores temporary maxes
int secCounter = 0; //Stores final max
for(int j = 0; j<a.length-1; j++){ // Iterate through array
if(a[j] == a[j+1]-1){
counter++; // If match found then increment counter
if(counter > secCounter)
secCounter = counter; // If current match is greater than stored match, replace current match
}
else
counter = 0; // Reset match to accumulate new match
}
System.out.println(secCounter);
As for your method, the first thing I noticed is that max has value of greatest number in array and not the size of array. So if my array is something like {1,2,3,45,6,7,8,9}, it will throw indexOutOfBoundsException because its gonna try get 45th element in array which is not present.

Why am I receiving an ArrayIndexOutofBoundsException?

In my JAVA code, I am given a data and I have to find the mode. Everything successfully compiled, and every method works. However, when I try to access the mode, I get an java.lang.ArrayIndexOutOfBoundsException: 987 in my terminal window. The highlighted portion is in the following method, which is one of my max methods. The data array, by the way, is just int [] data.
public int maxOfData(int [] oa)
{
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
return max;
}
The exception is on the line if(oa[i] > max)
And the mode code is this:
public int[] modeOfData()
{
int[] tally = new int[maxOfData() + 1];
for( int i = 0; i < size; i++)
{
tally[data[i]]++;
}
//max contains frequency of modes
int max = maxOfData (tally);
int count = 0;
for( int i = 0; i < tally.length; i++)
{
if( tally[i] == max )
count++;
}
//count occurence of maxValue in tally (for)
//that determines how many modes there are
//declare another int called modes
int[] modes = new int[count];
//size of array should be count
//loop through tally and extract modes: it's the index value.
int pos = 0;
for( int i = 0; i < tally.length; i++)
{
if(tally[i] == count)
modes[pos++] = i;
}
return modes;
//modes are where the values are == max
}
My other max for data is the same but data instead of oa. I need both max methods, just like that, according to my teacher. So what do I do? How do I fix this?
I think the line
for (int i = 1; i < size; i++)
should be
for (int i = 1; i < oa.length; i++)
ArrayIndexOutOfBound Exception is thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array. Whenever you iterate an Array object. you need to iterate while checking the index is always lesser than its length
for example,
for(int i=1;i<array.length;i++){
//access array content in ith position
System.out.println(array[i]);
}
Your size variable has the value of an illegal array index. that's the problem
Look at the number stored into size and then check to see what size you declared oa[] to be. If size is bigger than the size of oa[] then you have a problem.
Problem is in this part of code
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
rewrite the method maxOfData(int [] oa) with proper checks like this
public int maxOfData(int[] oa) {
if (oa == null) {
throw new IllegalArgumentException("Input array is null");
}
int max=oa[0];
for (int i = 1; i < oa.length; i++) {
if (oa[i] > max)
max = oa[i];
}
return max;
}
if input array is null it should not be processed.

Array of 20 rolls of one die in java

I'm working on an exercise that requires that I print 20 rolls of a die out and group repeated values in parentheses. My code below follows the pseudocode the book I'm reading says to use. I am able to group the repeated values in parentheses but the next exercise requires that I group the values that are repeated the most in parentheses.
For example:
(333)51314121(22)326(55)14
would be:
(333)51314121223265514
EDIT: If there is more than one largest group of repeated values only the first is to be grouped in parentheses.
How can I accomplish this? Many thanks in advance for any help on this.
public void run() {
Random generator = new Random();
ArrayList<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 21; i++) {
int die = generator.nextInt(6)+ 1;
a.add(die);
}
for (int j = 0; j < a.size() - 1; j++) {
if (inRun) {
if (a.get(j) != a.get(j - 1)) {
System.out.print(")");
inRun = false;
}
}
else {
if (a.get(j) == a.get(j + 1)) {
System.out.print("(");
inRun = true;
}
}
System.out.print(a.get(j));
}
if (inRun) {
System.out.print(")");
}
}
You don't really need a data structure other than an ordinary array.
You can make it O(n) by checking while inserting:
If the added number equals the previous, you increment the sequence count - if not, you reset the count.
When you increment a sequence count, check if it is bigger than the already stored max sequence count length - if it is bigger, the current sequence count becomes the max sequence count.
Check the code - some comments there to help understanding (run demo online here):
public void run() {
Random generator = new Random();
int[] a = new int[20];
int biggerSequence = 1; // starts pointing to the first char
int biggerSequenceEndIndex = 1; // starts pointing to the first char
int currentSequence = 1;
int previous = -1;
for (int i = 0; i < 20; i++) {
int die = generator.nextInt(6)+ 1;
a[i] = die;
if (die == previous) { // if inserted equals previous
currentSequence++; // increment sequence
if (currentSequence > biggerSequence) { // if it is bigger than max
biggerSequence = currentSequence; // max becomes it
biggerSequenceEndIndex = i+1;
}
} else {
previous = die;
currentSequence = 1; // reset the count
}
}
for (int i = 0; i < a.length; i++) {
if (i == biggerSequenceEndIndex-biggerSequence) { System.out.print("("); }
System.out.print(a[i]);
if (i+1 == biggerSequenceEndIndex) { System.out.print(")"); }
}
}
Example outputs:
(1)2345678901234567890
(11)345678901234567890
1(22)45678901234567890
1(22)45578901234567890
123456789012345678(99)
54(3333)43514564513551
You need to make multiple passes over the array. Go through it once and tally up how long all the runs are. Then decide what the maximum run length is. Finally, go back and print out the array, putting parentheses around runs of the maximum length.
Try something like this (exact implementation left to you):
runContents = a list containing the first random number
runLength = [1], i.e. a one element list with the number 1 in it
maxLength = 1
for each subsequent random number you want to consider {
if the last element of runContents == the next random number {
add 1 to the last element of runLength
} else {
if maxLength < the last element of runLength {
maxLength = the last element of runLength
}
append the random number to runContents
append a 1 to runLength
}
}
i = 0
while i < length(runContents) {
if runLength[i] == maxLength {
print runLength[i] copies of runContents[i] surrounded by parens
} else {
print runLength[i] copies of runContents[i]
}
}
Just try storing the number of repeated values starting at any given index. Something like:
public void run(){
Random generator = new Random();
ArrayList<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 21; i++) {//Generate your numbers
int die = generator.nextInt(6)+ 1;
a.add(die);
}
//store the number of repeats by index. (index is key, # of repeats is key)
HashMap<Integer, Integer> repeats = new HashMap<Integer, Integer>();
//This will find store the number of repeated numbers starting at any given index.
int index = 0;
repeats.put(index, 1);
for(int i = 1; i < a.size(); i++){
if(a.get(i) == a.get(index)){//Repeated values occurring
repeats.put(index, repeats.get(index) + 1);
} else {//End of a repeated sequence (even if that sequence was only 1 number long)
repeats.put(i, 1);
index = i;
}
}
//Find the index at which the maximum number of repeats occurs
int max = 0;
int startIndex = 0;
for(Integer i : repeats.keySet()){
//If the number of repeats is bigger than anything seen before
if(repeats.get(i) > max){
//Store the number of repeats and the index at which they start
max = repeats.get(i);
startIndex = i;
}
}
//print everything out
for(int i = 0; i < a.size(); i++){
if(i == startIndex)//Prints the open parenthesis before the repeats start
System.out.print("(");
System.out.print(a.get(i)); //Prints the number
if(i == startIndex + max)
System.out.print(")");//Prints the close parenthesis after the repeats end
}
}
Note that this algorithm assumes that there is only 1 repeated sequence of the maximum size. Should there be multiple that you want to keep, you'll have to store all indexes in another list. But that's a minor fix to the solution that would look like so:
ArrayList<Integer> startIndeces = new ArrayList<Integer>();
int max = 0;
for(Integer i : repeats.keySet()){
//If the number of repeats is bigger than anything seen before
if(repeats.get(i) > max){
//Store the number of repeats and the index at which they start
max = repeats.get(i);
startIndeces = new ArrayList<Integer>();
startIndeces.add(i);
} else if(repeats.get(i) == max)
startIndeces.add(i);
}
Otherwise the algorithm stores the first instance of the longest sequence.

Finding modes an an array

Does anyone know how to find the modes in an array when there are more then one mode? I have this code that finds one mode. But I'm dealing with an array which has more than one mode, a multimodal array and I have to print each mode exactly once. Here is my code, can someone help me out? Thanks.
public static int mode(int a[])
{
int maxValue=0, maxCount=0;
for (int i = 0; i < a.length; ++i)
{
int count = 0;
for (int j = 0; j < a.length; ++j)
{
if (a[j] == a[i]) ++count;
}
if (count > maxCount)
{
maxCount = count;
maxValue = a[i];
}
}
return maxCount;
}
public static Integer[] modes(int a[])
{
List<Integer> modes = new ArrayList<Integer>();
int maxCount=0;
for (int i = 0; i < a.length; ++i)
{
int count = 0;
for(int j = 0; j < a.length; ++j)
{
if (a[j] == a[i]) ++count;
}
if (count > maxCount)
{
maxCount = count;
modes.clear();
modes.add(a[i]);
}
else if (count == maxCount)
{
modes.add(a[i]);
}
}
return modes.toArray(new Integer[modes.size()]);
}
Since your elements will be between 10 and 1000, you can use a Counter array. In this Counter array, you can store the counts of the value of the a[i] element. I think you can understand this better in code:
public static List<Integer> mode(int[] a) {
List<Integer> lstMode = new ArrayList<Integer>();
final int MAX_RANGE = 1001;
int[] counterArray = new int[MAX_RANGE]; //can be improved with some maths :)!
//setting the counts for the counter array.
for (int x : a) {
counterArray[x]++;
}
//finding the max value (mode).
int maxCount = counterArray[0];
for(int i = 0; i < MAX_RANGE; i++) {
if (maxCount < counterArray[i]) {
maxCount = counterArray[i];
}
}
//getting all the max values
for(int i = 0; i < MAX_RANGE; i++) {
if (maxCount == counterArray[i]) {
lstMode.add(new Integer(i));
}
}
return lstMode;
}
If your input will have elements outside of 1000, you can look for the Map answer (like in other posts).
We should do this the easy way and utilize a Map data structure in the following format:
Map<Integer,Integer>
And then keep a running total, afterwards you iterate over the keyset and pull the highest value(s) from the Map.
If you want to stay with the List implementation you can do the following to remove dupes:
Set s = new HashSet(list);
list = new ArrayList(s);
One approach is to run (approximately) your current code twice: the first time, find maxCount, and the second time, print out each value that occurs maxCount times. (You'll need to make some modifications in order to print each mode only once, instead of printing it maxCount times.)
Instead of having a single maxValue, store the modes in an ArrayList<Integer>.
if (count == maxCount)
{
modes.add(a[i]);
}
else if (count > maxCount)
{
modes.clear(); // discard all the old modes
modes.add(a[i]);
maxCount = count;
}
and start with j = i instead of j = 0.
Since your array values only range from [10,1000], you could use a Map<Integer,Integer> to store a mapping between each discovered array value (map key) and its count (map value). A HashMap would work very well here.
To increment the count:
int count = (map.contains(a[i]) ? map.get(a[i]) : 1;
map.put(a[i],count);
Continue to track the max count like you already do, and at the end, just iterate over the map and collect all map keys with a map value equal to the max count.

Find the mode (most frequent value in an array) using a simple for loop?

How do I find the mode (most frequent value in an array) using a simple for loop?
The code compiles with a wrong output.
Here is what I have:
public static void mode(double [] arr)
{
double mode=arr[0];
for(int i = 1; i<arr.length; i++)
{
if(mode==arr[i])
{
mode++;
}
}
return mode;
}
First I sort the array by order and then I count occurrences of one number. No hashmaps only for loop and if statements.
My code:
static int Mode(int[] n){
int t = 0;
for(int i=0; i<n.length; i++){
for(int j=1; j<n.length-i; j++){
if(n[j-1] > n[j]){
t = n[j-1];
n[j-1] = n[j];
n[j] = t;
}
}
}
int mode = n[0];
int temp = 1;
int temp2 = 1;
for(int i=1;i<n.length;i++){
if(n[i-1] == n[i]){
temp++;
}
else {
temp = 1;
}
if(temp >= temp2){
mode = n[i];
temp2 = temp;
}
}
return mode;
}
-Just use a HashMap which contains the array index values as the keys and their occurrence numbers as the values.
-Update the HashMap as you traverse the for loop by checking to see if the current index already exists in the HashMap. IF IT DOES then find that double in the hash map and see how many times it has already occurred and put it back in the HashMap with one more occurrence.
-I did it in Java because that's what it looks like you are using. What's also good is that the time complexity is O(n) which is the best you could possibly get for this type of scenario because you have to visit every element at least once.
-So if you have an array like this of doubles: { 1,2,3,1,1,1,5,5,5,7,7,7,7,7,7,7,7,7}
Then the hash map will look something like this at the end: { 1->4, 2->1, 3->1, 5->3, 7->9 }
Meaning that "1 occurred 4 times, 2 occured 1 time .... 7 occurred 9 times" etc.
public static double mode(double [] arr)
{
HashMap arrayVals = new HashMap();
int maxOccurences = 1;
double mode = arr[0];
for(int i = 0; i<arr.length; i++)
{
double currentIndexVal = arr[i];
if(arrayVals.containsKey(currentIndexVal)){
int currentOccurencesNum = (Integer) arrayVals.get(currentIndexVal);
currentOccurencesNum++;
arrayVals.put(currentIndexVal, currentOccurencesNum );
if(currentOccurencesNum >= maxOccurences)
{
mode = currentIndexVal;
maxOccurences = currentOccurencesNum;
}
}
else{
arrayVals.put(arr[i], 1);
}
}
return mode;
}
This code is a different way that does not use hashmaps. This method, created in java, takes an array as the parameter and creates another array called "numberCount" within the method. This array "numberCount" will set its index to the value in the array. The index of "numberCount"that contains the value in the array passed will add 1 to the value of "numberCount" ("++numberCount[array[i]]") then will go to the next value in the array (repeat until the end of the array). Then creates another for loop to go through each value of the array in "numberCount", which ever index has the highest value/count will be stored and return as "max." This method will have to undergo some difficult changes to use a double array. but seems to work great with an int array.
public static int findMostFrequentValue(int[] array) {
int i;
int[] numberCount = new int[100];
for (i = 0; i < array.length; i++)++numberCount[array[i]];
int max = 0;
int j;
for (j = 0; j < numberCount.length; j++) {
if (numberCount[j] > max) max = j;
}
return max;
}
You should check the number of occurances of every element in your array. You can do it by comparing every element of array with herself and others via 2 inner for loops.
Remember, if the array is not sorted and contains more then 1 modal value (thus repeating number of occurances) this will return the first one. It maybe wise to order the array first by Arrays.sort(array) so that you can pick the smallest or biggest modal value.
public static int modeOfArray(int[] array){
int mode;
int maxOccurance = 0;
for(int i=0; i<array.length; i++){
int occuranceOfThisValue = 0;
for(int j=0; j<array.length; j++){
if(array[i] == array[j])
occuranceOfThisValue++;
}
if(occuranceOfThisValue > maxOccurance){
maxOccurance = occuranceOfThisValue;
mode = array[i];
}
}
return mode;
}

Categories

Resources