【问题标题】:indexing a java matrix索引一个java矩阵
【发布时间】:2011-11-13 13:27:10
【问题描述】:

我想知道是否可以对矩阵的多列进行索引以加快排序速度。在 MySQL 中,您可以在多个列上建立索引,这使得在表中查找元素的速度更快,但我不知道这在标准 java 矩阵中是否可行。例如,我的数据是一个 3 列矩阵,它有一个 id、名字和姓氏,然后是这个表上的许多条目。现在我可以说类似 mat[5] 的内容并获取 id 为 5 的个人的条目,但我也希望能够按姓氏列搜索条目。我怎样才能在 Java 中最有效地做到这一点?

【问题讨论】:

    标签: java indexing matrix


    【解决方案1】:

    如果是 Java,您始终可以设置一个哈希表,将姓氏与矩阵行索引数组相关联,这样这些行上的人就拥有该姓氏。

    或者你可以有一个多级哈希表,这样你就可以做到m[index.get(lastName).get(firstName)]

    此外,如果您想按字典顺序遍历名称,可以将哈希表替换为 TreeMap

    例子:

    import java.util.*;
    class Test{
        public static void main(String[]args){
    
            Object[][] m = new Object[][]{
                {1, "Smith", "John"},
                {2, "Stone", "Jack"},
                {3, "Stein", "Robert"},
                {4, "Stone", "Bob"}
            };
    
            //index.get(lastName) will return a map between
            //first names and matrix row indices. 
            //index.get(lastName).get(firstName) returns the index
            //in the matrix of the row pertaining to person (lastName, firstName)
            TreeMap<String, TreeMap<String, Integer>> index = 
                new TreeMap<String, TreeMap<String, Integer>>();
    
            //create index
            for(int i=0;i<m.length;i++){
                Object[]o = m[i];
                String last = o[1].toString();
                String first = o[2].toString();
                TreeMap<String,Integer> index2 = index.get(last);
                if (index2==null){
                    index2=new TreeMap<String,Integer>();
                    index.put(last, index2);
                }
                index2.put(first, i);
            }
    
            System.out.print("Smith, John -> ");
            System.out.println(Arrays.toString(m[index.get("Smith").get("John")]));
    
            System.out.print("Stone -> ");
            System.out.println(index.get("Stone"));
    
            System.out.print("Full index: ");
            System.out.println(index); 
        }
    }
    

    输出:

    Smith, John -> [1, Smith, John]
    Stone -> {Bob=3, Jack=1}
    Full index: {Smith={John=0}, Stein={Robert=2}, Stone={Bob=3, Jack=1}}
    

    在我给出的示例中,将姓氏映射到行索引是不够的,因为您可能有两个姓氏相同的人。但是,我确实假设您不会有两个同名的人。否则,您将需要TreeMap&lt;String, TreeMap&lt;String, ArrayList&lt;Integer&gt;&gt;&gt; 之类的东西,以便能够找到具有给定(姓氏、名字)的每个人。 如果要按 ID 搜索,只需创建第二个索引,将 ID 映射到行索引,可以是 HashMap&lt;Integer, Integer&gt;

    对于这个小例子,拥有索引并没有什么好处,因为它们可能比矩阵本身占用更多的空间,但如果你的记录很大,它可能会得到回报。

    【讨论】:

    • 嘿抱歉,我不完全理解您将如何实施您的建议。如果我有一个数组,并且每个插槽都指向一个散列,并且这些散列中的每个键都指向其他散列,那如何让我按姓氏搜索?假设条目是1 - Smith, John,2 - Stone, Jack,3 - Stein, Robert。你能告诉我如何使用你的代码通过它的 id (2) 和它的姓氏 (Stone) 搜索第二个条目吗?
    【解决方案2】:

    一般来说,如果您想要以多种方式访问​​ Java 数据结构,您将不得不创建额外的“并行”结构。

    例如,您可以让您的“主表”——无论是数组还是列表或其他任何东西——按名称排序或键控。然后,您将创建第二个按客户编号排序的表,并且该表中的每个条目都可以保存第一个表的索引或对象句柄的另一个副本。然后你可以有第三个按出生日期排序的表,其条目也指向第一个表,等等。

    例如:

    class Customer
    {
      public String name;
      public int customerNumber;
      public int shoeSize;
      ... whatever ...
    }
    class byName implements Comparator<Customer>
    {
      public int compareTo(Customer c1, Customer c2)
      {
        return c1.name.compareTo(c2.name);
      }
    }
    class byShoeSize implements Comparator<Customer>
    {
      public int compareTo(Customer c1, Customer c2)
      {
        return c1.shoeSize-c2.shoeSize;
      }
    }
    
    ... elsewhere ...
    Customer[] nameOrder=new Customer[100];
    nameOrder[0]=new Customer("Fred Smith", 10001, 9);
    nameOrder[1]=new Customer("Mary Jones", 10002, 7);
    ... etc, however we get the list initialized ...
    Arrays.sort(nameOrder, byName);
    
    Customer[] shoeSizeOrder=new Customer[100];
    for (int n=0;n<customerList.length;++n)
      byNumber[n]=customerList[n];
    Arrays.sort(shoeSizeOrder, byShoeSize);
    

    (通常的免责声明:未经测试的代码在我脑海中浮现。请原谅任何语法错误。省略错误检查和其他过度简化以给出想法。等等)

    在此之后,您将获得一个按名称排序的列表和另一个按鞋码排序的列表。然后,您可以按顺序扫描每个列表,二进制搜索以查找特定值等。

    当然没有说所有的列表都必须是数组。它们可以是哈希表、数组列表或任何其他有序或具有键/值映射的结构。

    请注意,这不是同一数据的两个副本。只有一组对象。每个对象只有两个 HANDLES,每个列表中都有一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-17
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2012-12-29
      • 1970-01-01
      相关资源
      最近更新 更多