0

If I have a 2D array that is arranged as follows :

  String X[][] = new String [][] {{"127.0.0.9", "60", "75000","UDP", "Good"},
                              {"127.0.0.8", "75", "75000","TCP", "Bad"},
                      {"127.0.0.9", "75", "70000","UDP", "Good"},
                      {"127.0.0.1", "", "70000","UDP", "Good"},
                      {"127.0.0.1", "75", "75000","TCP", "Bad"}
                                   };

I want to know the frequency of each value .. so I27.0.0.9 gets 2. How can I do a general solution for this ? In Java or any algorithm for any language ?

4 Answers 4

3

It looks like you need a custom data type to encapsulate each row rather than using a String[][], but to answer your question more directly, you can use a Map<String,Integer> for each column. A HashMap<String,Integer> can be expected to do this in optimal time.


Here's a snippet to demonstrate the idea:

import java.util.*;

public class Frequency {
    static void increment(Map<String,Integer> map, String key) {
        Integer count = map.get(key);
        map.put(key, (count == null ? 0 : count) + 1);
    }
    public static void main(String[] args) {
        String table[][] = new String[][] {
            {"127.0.0.9", "60", "75000","UDP", "Good"},
            {"127.0.0.8", "75", "75000","TCP", "Bad"},
            {"127.0.0.9", "75", "70000","UDP", "Good"},
            {"127.0.0.1", "", "70000","UDP", "Good"},
            {"127.0.0.1", "75", "75000","TCP", "Bad"}
        };
        final int M = table.length;
        final int N = table[0].length;
        List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
        for (int i = 0; i < N; i++) {
            maps.add(new HashMap<String,Integer>());
        }
        for (String[] row : table) {
            for (int i = 0; i < N; i++) {               
                increment(maps.get(i), row[i]);
            }
        }
        for (Map<String,Integer> map : maps) {
            System.out.println(map);
        }
        System.out.println(maps.get(0).get("127.0.0.9"));
    }
}

This produces the following output: each line is a frequency map for each column:

{127.0.0.9=2, 127.0.0.8=1, 127.0.0.1=2}
{=1, 60=1, 75=3}
{75000=3, 70000=2}
{UDP=3, TCP=2}
{Good=3, Bad=2}
2

Note: if you don't care about mixing values from all columns together, then you only need one Map, instead of a List<Map> one for each column. This would make the design even worse, though. You really should encapsulate each row into a custom type, instead of a having everything mixed as String[][].

For example some of those columns really looks like they should be an enum.

enum Protocol { UDP, TCP; }
enum Condition { Good, Bad; }
//...
Sign up to request clarification or add additional context in comments.

Comments

1

You can use Map for Java as above question, use Dictionary for C# The general algorithm is that you have a table/ array of key - value. And you can give the datastructure a key, it will find for you the correct value for that key

Comments

1

Don't store everything as Strings. This slows down processing and is not elegant. Why store a port number (which is an int) as a string? or a boolean value "good" "bad" as a string? Create a custom class that have fields with types corresponding to their semantic.

Comments

1
// I think this is an example of what Vodkhang is describing

public static void main(String[] args){
  String X[][] = new String [][] {{"127.0.0.9", "60", "75000","UDP", "Good"},
                          {"127.0.0.8", "75", "75000","TCP", "Bad"},
                  {"127.0.0.9", "75", "70000","UDP", "Good"},
                  {"127.0.0.1", "", "70000","UDP", "Good"},
                  {"127.0.0.1", "75", "75000","TCP", "Bad"}
                               };

   final int M = X.length;
   final int N = X[0].length;

   HashMap<Object, ArrayList> map = new HashMap();

   for(int i = 0; i < M; i++){
       for(int j = 0; j < M; j++){
           String s = X[i][j];
           if( map.containsKey(s) ){
               // add the string to the existing array list
               ArrayList al = map.get(s);
               al.add(s);
               map.put(s,al);
           } else {
               // make a new node
               ArrayList al = new ArrayList();
               al.add(s);
               map.put(s, al);
           }
       }
   }

   // now loop through each pair in the map
   // for each arraylist print out the size
   Set<Object> set = map.keySet();
   for(Object s: set){
       ArrayList al = map.get(s);
       System.out.println(s.toString() + " " + al.size() );
   }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.