0

I've written a java prog that stores some values:

public class array05 {
    public static void main(String[] args) {

        //placement of value
        int arryNum[] = {2,3,4,5,4,4,3};

        //placement of index, to start at 0
        for(int counter=0;counter<arryNum.length;counter++){
            System.out.println(counter + ":" + arryNum[counter]);
        }
    }   
}

which generate such output:
0:2
1:3
2:4
3:5
4:4
5:4
6:3

and now I need to count numbers in this output #1. Output #2 should be this:

1: 0
2: 1
3: 2
4: 3
5: 1

It means it counts ONE 2, TWO 3, THREE 4, and only One 5.

I am not sure how to write the code for output 2. Is a binary search needed here?

can anybody shed a light?

Ree
  • 259
  • 1
  • 4
  • 16

10 Answers10

5

if you are expecting in your array values between 1-5 (i assuming this from your expected output)

int arryNum[] = { 2, 3, 4, 5, 4, 4, 3 };
int[] counter = new int[] { 0, 0, 0, 0, 0 };
for (int i = 0; i < arryNum.length; i++) {
    counter[arryNum[i] - 1]++;
}

for (int i = 0; i < counter.length; i++)
    System.out.println((i + 1) + ":" + counter[i]);
user902383
  • 8,420
  • 8
  • 43
  • 63
  • thank you for helping out, i can easily understand by this approach! However I don't understand this part [arryNum[i] - 1], do you mind explaining? – Ree Oct 31 '13 at 12:21
  • It is easily understood but if the array contains values that are not between 1 to 5, then it breaks. For this array for instance: `{ 0, 2, 3, 4, 5, 4, 4, 3 }`. Since the numbers don't appear to represent anything that can only be between 1-5, this is not good practice. (may be ok for homework) – Ben Barkay Oct 31 '13 at 12:27
  • @rzrz indexes in arrays are from 0, while your numbers starts from 1 – user902383 Oct 31 '13 at 12:51
  • @BenBarkay you are right, i said that, this is not universal solution, and it will work only for entries in given range – user902383 Oct 31 '13 at 12:53
4

I advise you to use a Map:

  • If a number doesn't exist in it, add it with the value of 1.
  • If the number exists, add 1 to the its value.

Then you print the map as a key and value.

For example, for your array {2,3,4,5,4,4,3} this will work as follows:

Does the map contains the key 2? No, add it with value 1. (The same for 3, 4 and 5)
Does the map contains 4? Yes! Add 1 to its value. Now the key 4 has the value of 2.
...

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • No time like the present to learn Maps! Far to useful to ignore, and the easiest way to solve this problem! – NickJ Oct 31 '13 at 11:48
  • FYI: If the implementation assumes all map values (not keys) must not be null, instead of checking to see if a key exists, just attempt to get the value with the key. If it returns null, you know the key doesn't exist either. This is WAY faster than looping through the keys (which is what happens when you say "containsKey"). It's O(1) vs O(n). – MadConan Oct 31 '13 at 11:59
3

This is a solution to this problem:

import java.util.Arrays;

public class array05 {
    public static void main(String[] args) {
        //placement of value
        int arryNum[] = {2,3,4,5,4,4,3};

        // Sort the array so counting same objects is easy
        Arrays.sort(arryNum);

        int index = 0;  // The current index
        int curnum;     // The current number
        int count;      // The count of this number
        while (index < arryNum.length) {
            // Obtain the current number
            curnum = arryNum[index];

            // Reset the counter
            count = 0;

            // "while the index is smaller than the amount of items
            // and the current number is equal to the number in the current index,
            // increase the index position and the counter by 1"
            for (; index < arryNum.length && curnum == arryNum[index]; index ++, count++);

            // count should contain the appropriate amount of the current
            // number now
            System.out.println(curnum + ":" + count);
        }
    }   
}

People posted good solutions using Map, so I figured I'd contribute a good solution that will always work (not just for the current values), without using a Map.

Ben Barkay
  • 5,473
  • 2
  • 20
  • 29
  • hi thanks for your help, but if I do not have ONE in the array, how to display it as such? Eg - 1:0 – Ree Oct 31 '13 at 12:36
  • Your statement: "It means it counts ONE 2, TWO 3, THREE 4, and only One 5." led me into thinking it only has to count items that are present in the array. I'm sorry if this doesn't fit your needs :) – Ben Barkay Oct 31 '13 at 12:41
  • 1
    This is not O(n) complexity, but at least O(n log(n)) – user902383 Oct 31 '13 at 13:04
  • 1
    No worries, your code & detailed comment have show me another way to tackle this! Thank you for your time – Ree Oct 31 '13 at 13:06
  • @user902383 I was wrong about `Arrays.sort` complexity :) Thank you for letting me know. – Ben Barkay Oct 31 '13 at 13:45
3
If you don't want to use Map, this is how you would do it with Arrays only(if you have numbers from 1 to 9 only)

Integer[] countArray = new Integer[10]

// Firstly Initialize all elements of countArray to zero
// Then
for(i=0;i<arryNum.length();i++){

int j = arryNum[i];
countArray[j]++;

}

This countArray has number of 0's in 1st position, number of 1s in 2nd position and so on

The_Lost_Avatar
  • 992
  • 5
  • 15
  • 35
2

Something like this:

//numbers to count
int arryNum[] = {2,3,4,5,4,4,3};

//map to store results in
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();

//Do the counting
for (int i : arryNum) {
   if (counts.containsKey(i) {
      counts.put(i, counts.get(i)+1);
   } else {
      counts.put(i, 1);
   }
}

//Output the results
for (int i : counts.keySet()) {
   System.out.println(i+":"+counts.get(i));
}
NickJ
  • 9,380
  • 9
  • 51
  • 74
  • No-one spotted the deliberate mistake - I has hasKey() instead of containsKey(). Corrected now. :) – NickJ Oct 31 '13 at 12:04
2

Use Map to store count values:

import java.util.HashMap;
import java.util.Map;

class array05{
  public static void main(String[] args){
      // Container for count values
      Map <Integer, Integer> result = new HashMap<Integer, Integer>();
      int arryNum[] = {2,3,4,5,4,4,3};
      for(int i: arryNum){ //foreach more correct in this case
            if (result.containsKey(i)) result.put(i, result.get(i)+1);
            else result.put(i, 1);
        }
        for (int i: result.keySet()) System.out.println(i + ":" + result.get(i));
  }
}

Result below:

2:1
3:2
4:3
5:1
Michael Kazarian
  • 4,376
  • 1
  • 21
  • 25
  • thank you for the map suggestion, how about if I want to include number that isn't in the array? Eg: There is no number One therefore the output is 1:0 – Ree Oct 31 '13 at 12:08
  • It possible, but more complex. In this case you must not use generics. May be you it require using `getClass` (http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html) for transformation from `Object` – Michael Kazarian Oct 31 '13 at 12:18
1

One approach is to use a map. When you read the first array on each number check if it exists in the map, if it does then just increment the value assigned to the number(key), if not then create a new key in the map with value "1".

Check out http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

Dropout
  • 13,653
  • 10
  • 56
  • 109
1

You can try this way too

 int arrayNum[] = {2,3,4,5,4,4,3};
    Map<Integer,Integer> valMap=new HashMap<>();
    for(int i:arrayNum){ // jdk version should >1.7
        Integer val=valMap.get(i);
        if(val==null){
            val=0;
        }
        valMap.put(i,val+1);
    }
    Arrays.sort(arrayNum);
    for(int i=0;i< arrayNum[arrayNum.length-1];i++){
        System.out.println(i+1+" : "+((valMap.get(i+1)==null) ? 0:valMap.get(i+1)));
    }

Out put

    1 : 0
    2 : 1
    3 : 2
    4 : 3
    5 : 1

But following way is better

    int arrayNum[] = {2,3,4,5,4,4,3};
    Arrays.sort(arrayNum);
    int countArray[]=new int[arrayNum[arrayNum.length-1]+1];
    for(int i:arrayNum){
       countArray[i]= countArray[i]+1;
    }
    for(int i=1;i<countArray.length;i++){
        System.out.println(i+" : "+countArray[i]);
    }

Out put

   1 : 0
   2 : 1
   3 : 2
   4 : 3
   5 : 1
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
1

I would prefer some generic solution like this one:

public static <T> Map<T, Integer> toCountMap(List<T> itemsToCount) {
    Map<T, Integer> countMap = new HashMap<>();

    for (T item : itemsToCount) {
        countMap.putIfAbsent(item, 0);
        countMap.put(item, countMap.get(item) + 1);
    }

    return countMap;
}
Vallerious
  • 570
  • 6
  • 13
0
//Count the times of numbers present in an array
private HashMap<Integer, Integer> countNumbersInArray(int[] array) {
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    for (int item : array) {
        if (hashMap.containsKey(item)) {
            hashMap.put(item, hashMap.get(item) + 1);
        } else {
            hashMap.put(item, 1);
        }
    }
    return hashMap;
}