2D数组值频率

时间:2010-05-15 14:27:42

标签: java algorithm search

如果我有一个2D数组排列如下:

  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"}
                                   };

我想知道每个值的频率..所以I27.0.0.9得到2.我怎么能为此做一般解决方案?在Java或任何语言的任何算法?

4 个答案:

答案 0 :(得分:3)

您似乎需要自定义数据类型来封装每一行而不是使用String[][],但为了更直接地回答您的问题,您可以为每列使用Map<String,Integer>HashMap<String,Integer>可以在最佳时间内完成此任务。


这是一个展示这个想法的片段:

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"));
    }
}

这会产生以下输出:每一行是每列的频率图:

{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

注意:如果您不关心将所有列的值混合在一起,那么每列只需要一个Map,而不是List<Map>。但这会使设计更糟糕。你真的应该将每一行封装成一个自定义类型,而不是将所有内容混合为String[][]

例如,其中一些列看起来应该是enum

enum Protocol { UDP, TCP; }
enum Condition { Good, Bad; }
//...

答案 1 :(得分:1)

您可以使用Map for Java作为上述问题,使用Dictionary for C# 一般算法是你有一个键/值的表/数组。并且您可以为数据结构提供密钥,它将为您找到该密钥的正确值

答案 2 :(得分:1)

不要将所有内容存储为字符串。这会减慢处理速度并且不优雅。为什么将端口号(这是一个int)存储为字符串?或者一个布尔值“good”“bad”作为字符串?创建一个自定义类,其字段的类型与其语义相对应。

答案 3 :(得分: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() );
   }

}