views:

47

answers:

2

Need to put the frequency of each number occurrence into a 1D array and output the result. The 2D to 1D part is throwing me off, I'm not terribly comfortable with arrays yet.

public static void main( String[] args ){

  int matrix [][]=new int[20][2];

  for (int row=0;row<matrix.length;row++){
    for (int column=0;column<matrix[row].length;column++)
      matrix[row][column]=(int)(Math.random()*12+1);

  }
   frequency(matrix);




public static int frequency(int [][] matrix){
   int [] nums =[12];
   int count =0;
   for (int i=0;i<matrix.length;i++){
      for (int j=0; j<matrix[i].length;j++)
            (???)

       }
   return (?);
+2  A: 

Something like this I would guess :

public static int[] frequency(int [][] matrix){
    int [] nums =[14];      // max value can be 13 so you need 14 element
    int count =0;
    for (int i=0;i<matrix.length;i++){
        for (int j=0; j<matrix[i].length;j++) {
            nums[matrix[i][j]] += 1;
        }
    }
    return nums;
}

This is a bit of a contrived example, as normally the values to be collected do not nicely fall on an array index, so a hashmap would be a more typical solution.

Actually it would be more fun to multiply 2 random numbers (Like Math.random()*Math.random() + 1 ) to fill the matrix, then you get a nice bell curve instead of boring white noise in your final frequency distribution.

Peter Tillemans
"Actually it would be more fun to multiply 2 random numbers (Like Math.random()*Math.random() + 1 ) to fill the matrix, then you get a nice bell curve instead of boring white noise in your final frequency distribution."Funny you should mention that, I plan on doing that actually, it will have another array that does that.
S.Jaub
ROTFL. :-) Glad I could help.
Peter Tillemans
A: 

If you know in advance that that the numbers are in a specified range (i.e. from 1 to 13, according to your code), you can adopt a simple solution like the one from Peter Tillemans.

Another solution is to use a Map to store the frequencies of the numbers contained in the matrix.

public static Map<Integer, Integer> frequency(int[][] matrix) {
    Map<Integer, Integer> frequencies = new HashMap<Integer, Integer>();

    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            Integer frequency = 0;

            if (frequencies.containsKey(matrix[i][j])) {
                frequency = frequencies.get(matrix[i][j]);
            }

            frequencies.put(matrix[i][j], frequency + 1);
        }
    }

    return frequencies;
}

If exposing the Map interface to the external code is not what you want, you can also write a custom data type to hold the results. In this way, you can hide the implementation of the results (arrays, maps, or anything else) and provide only the methods you really need.

public class FrequencyResults {

    private Map<Integer, Integer> frequencies;

    public FrequencyResults() {
        frequencies = new HashMap<Integer, Integer>();
    }

    public void increment(int number) {
        Integer frequency = 0;

        if (frequencies.containsKey(number)) {
            frequency = frequencies.get(number);
        }

        frequencies.put(number, frequency + 1);
    }

    public int get(int number) {
        Integer frequency = 0;

        if (frequencies.containsKey(number)) {
            frequency = frequencies.get(number);
        }

        return frequency;
    }

}

Using this data type, the frequency function evolves in the following code. I think that, with this small rewriting, you can express more effectively what your code does.

public static FrequencyResults frequency(int[][] matrix) {
    FrequencyResults results = new FrequencyResults();

    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            results.increment(matrix[i][j]);
        }
    }

    return results;
}
frm