Counting the number of integers in an array

I am writing a program that takes into account the occurrences of integers entered into an array, for example, if you enter 1 1 1 1 2 1 3 5 2 3, the program will print individual digits followed by their occurrences, for example

1 happens 5 times, 2 happens 2 times, 3 happens 2 times, 5 happens 1 time

And it almost ended, except for one problem, I cannot understand:

import java.util.Scanner; import java.util.Arrays; public class CountOccurrences { public static void main (String [] args) { Scanner scan = new Scanner (System.in); final int MAX_NUM = 10; final int MAX_VALUE = 100; int [] numList; int num; int numCount; int [] occurrences; int count[]; String end; numList = new int [MAX_NUM]; occurrences = new int [MAX_NUM]; count = new int [MAX_NUM]; do { System.out.print ("Enter 10 integers between 1 and 100: "); for (num = 0; num < MAX_NUM; num++) { numList[num] = scan.nextInt(); } Arrays.sort(numList); count = occurrences (numList); System.out.println(); for (num = 0; num < MAX_NUM; num++) { if (num == 0) { if (count[num] <= 1) System.out.println (numList[num] + " occurs " + count[num] + " time"); if (count[num] > 1) System.out.println (numList[num] + " occurs " + count[num] + " times"); } if (num > 0 && numList[num] != numList[num - 1]) { if (count[num] <= 1) System.out.println (numList[num] + " occurs " + count[num] + " time"); if (count[num] > 1) System.out.println (numList[num] + " occurs " + count[num] + " times"); } } System.out.print ("\nContinue? <y/n> "); end = scan.next(); } while (!end.equalsIgnoreCase("n")); } public static int [] occurrences (int [] list) { final int MAX_VALUE = 100; int num; int [] countNum = new int [MAX_VALUE]; int [] counts = new int [MAX_VALUE]; for (num = 0; num < list.length; num++) { counts[num] = countNum[list[num]] += 1; } return counts; } } 

The problem I am facing is that no matter what the current value for "num", "count" only prints 1, and the problem is not in the method that takes into account the occurrences, because when you enter numbers instead of a variable, it changes value.

Is there a way to change this so that it prints the entries correctly or do I need to try something else? And the simpler the solution, the better, since I have not yet passed arrays with one dimension.

Thanks for the help!

+8
java arrays counting
source share
5 answers

What should I say, it took me a while to figure out what the two variables count and countNum , maybe some comments are needed. But finally, I found an error.

Suppose the ten numbers entered are: 5, 6, 7, 8, 5, 6, 7, 8, 5, 6

After sorting numList : 5, 5, 5, 6, 6, 6, 7, 7, 8, 8

The count array returned by occurrences() should be: [1, 2, 3, 1, 2, 3, 1, 2, 1, 2]

In fact, the only useful numbers in this array of results are:

 count[2]: 3 count number for numList[2]: 5 count[5]: 3 count number for numList[5]: 6 count[7]: 2 count number for numList[7]: 7 count[9]: 2 count number for numList[9]: 8 

Other numbers, such as the first two numbers 1, 2 to 3 , are only used to calculate the sums of occurrences step by step, right? So, your loop logic should be changed as follows:

  • remove the first if block:

     if (num == 0) { if (count[num] <= 1) System.out.println (numList[num] + " occurs " + count[num] + " time"); if (count[num] > 1) System.out.println (numList[num] + " occurs " + count[num] + " times"); } 
  • Change the second if condition to:

     if ((num + 1) == MAX_NUM || numList[num] != numList[num + 1]) { ...... } 

After that, your code should work fine as expected.

By the way, you really don't need to do this so confusing. Just try the HashMap :)

+1
source share

Try HashMap. For this type of problem, hashes are very efficient and fast.

I am writing this function, which takes an array and returns a HashMap, whose key is a number and a value, is filling this number.

 public static HashMap<Integer, Integer> getRepetitions(int[] testCases) { HashMap<Integer, Integer> numberAppearance = new HashMap<Integer, Integer>(); for(int n: testCases) { if(numberAppearance.containsKey(n)) { int counter = numberAppearance.get(n); counter = counter+1; numberAppearance.put(n, counter); } else { numberAppearance.put(n, 1); } } return numberAppearance; } 

Now iterate through the hash map and print these numbers:

 HashMap<Integer, Integer> table = getRepetitions(testCases); for (int key: table.keySet()) { System.out.println(key + " occur " + table.get(key) + " times"); } 

Output:

enter image description here

+3
source share

I would use a bag, a collection that counts the number of times an item appears in the collection. Apache Commons has its implementation. Here is their interface , and here is a sorted tree-like implementation .

You would do something like this:

 Bag<Integer> bag = new TreeBag<Integer>(); for (int i = 0; i < numList.length; i++) { bag.add(numList[i]); } for (int uniqueNumber: bag.uniqueSet()) { System.out.println("Number " + uniqueNumber + " counted " + bag.getCount(uniqueNumber) + " times"); } 

The above example contains elements from your numList array and adds them to Bag to generate counters, but you don't need an array. Just add items to Bag directly. Something like:

 // Make your bag. Bag<Integer> bag = new TreeBag<Integer>(); ... // Populate your bag. for (num = 0; num < MAX_NUM; num++) { bag.add(scan.nextInt()); } ... // Print the counts for each unique item in your bag. for (int uniqueNumber: bag.uniqueSet()) { System.out.println("Number " + uniqueNumber + " counted " + bag.getCount(uniqueNumber) + " times"); } 
+2
source share

You can start by initializing an array of values ​​between MIN and MAX. Then you can add to each element of the array when this value has a value of 1 . Something like,

 Scanner scan = new Scanner(System.in); final int MAX_NUM = 10; final int MAX_VALUE = 100; final int MIN_VALUE = 1; final int SIZE = MAX_VALUE - MIN_VALUE; int[] numList = new int[SIZE]; System.out.printf("Enter %d integers between %d and %d:%n", MAX_NUM, MIN_VALUE, MAX_VALUE); for (int i = 0; i < MAX_NUM; i++) { System.out.printf("Please enter number %d: ", i + 1); System.out.flush(); if (!scan.hasNextInt()) { System.out.printf("%s is not an int%n", scan.nextLine()); i--; continue; } int v = scan.nextInt(); if (v < MIN_VALUE || v > MAX_VALUE) { System.out.printf("%d is not between %d and %d%n", v, MIN_VALUE, MAX_VALUE); continue; } numList[v - MIN_VALUE]++; } boolean first = true; for (int i = 0; i < SIZE; i++) { if (numList[i] > 0) { if (!first) { System.out.print(", "); } else { first = false; } if (numList[i] > 1) { System.out.printf("%d occurs %d times", i + MIN_VALUE, numList[i]); } else { System.out.printf("%d occurs once", i + MIN_VALUE); } } } System.out.println(); 

1 See also radix sorting counting sorting .

+1
source share

I think you can greatly simplify your code if you use this approach. You still have to modify to include MAX_NUM and MAX_VALUE .

 public static void main(String[] args) { Integer[] array = {1,2,0,3,4,5,6,6,7,8}; Stack stack = new Stack(); Arrays.sort(array, Collections.reverseOrder()); for(int i : array){ stack.push(i); } int currentNumber = Integer.parseInt(stack.pop().toString()) , count = 1; try { while (stack.size() >= 0) { if (currentNumber != Integer.parseInt(stack.peek().toString())) { System.out.printf("%d occurs %d times, ", currentNumber, count); currentNumber = Integer.parseInt(stack.pop().toString()); count = 1; } else { currentNumber = Integer.parseInt(stack.pop().toString()); count++; } } } catch (EmptyStackException e) { System.out.printf("%d occurs %d times.", currentNumber, count); } } 
0
source share

All Articles