双向名称ID关系的适当数据结构是什么?

时间:2010-07-30 19:41:56

标签: perl data-structures

我有一个学生姓名及其ID的列表。有时我需要使用id搜索名称,有时我需要使用名称搜索id。

  • 如果使用array[id] = name,则可以快速找到使用ID的名称但使用名称查找ID的速度很慢。
  • 如果使用hash{name} = id,则可以使用名称快速找到ID,但很难从ID中找到名称。

表示学生姓名关系的最佳数据结构是什么?注意:学生姓名是一个字符串,而id是从1到这些学生总数的连续整数。

感谢。

5 个答案:

答案 0 :(得分:4)

如果您尝试在不使用实际数据库的情况下执行此操作,那么您将需要两个索引。有几种方法可以做到这一点,你还没有真正给出足够的信息来解决你使用它的问题,但这里有一些适用于很多情况的东西:


# Store student records sequentially, in any convenient order
my @student =
  ( { id=27,  name => 'Alice Amber', class = 'X' }
  , { id=2,   name => 'Bob Brown',   class = 'y' }
  , ...
  , { id=104, name => 'Zacharia Zebra', class = 'x' }
  );

# build index by id
my @student_by_id;
$student_by_id[$student[$_]{id}] = $student[$_] for 0..$#student;

# build index by name
my %student_by_name;
$student_by_name{$student[$_]{name}} = $student[$_] for 0..$#student;

What that gives you is a single copy of the student records, stored in @student in arbitrary order, and two indexes called @student_by_id and %student_by_name。因为索引将引用存储到学生记录中,所以通过任一索引对记录所做的任何更改都将从另一个索引中可见。当您需要更改学生的姓名或身份证号码时,会出现唯一的障碍,因为这需要更新受影响的索引。

答案 1 :(得分:2)

你可以结合两种“快速”方法。使用数组查找id ->名称,并使用名称-> id的哈希值。

通过“数据库”,我假设你只是谈论一些数据结构(如数组或散列)而不是关系数据库(如MySQL)。

答案 2 :(得分:1)

我经常创建包含信息记录和不同索引哈希的哈希来定位它们。

my $record 
    = { name          => 'James'
      , rank          => 'Captain'
      , serial_number => '007'
      };

foreach my $field ( qw<name rank serial_number> ) { 
    my $ref = \$lookup{ $field }{ $record->{ $field } };
    if ( ref( $$ref ) eq 'ARRAY' || !$lookup{meta}{$field}{is_unique} ) { 
        push @$ref, $record;
    }
    else { 
        $$ref = $record;
    }
}

这是胆量,虽然我可能会封装记录和查找机制。

答案 3 :(得分:0)

一种方法是使用这两种实现。当您需要来自id的名称时使用数组,并在需要名称时使用哈希时使用哈希。不确定这是不是最好的方式。

答案 4 :(得分:0)

同时使用数组和哈希。您的问题是this question的特例。

在Perl中,您可以使用tie机制创建一个看起来像哈希的类,并使用另一个方法按ID查找,但添加和删除的内容同时维护哈希和一个数组

Tie::Hash::TwoWay提供双向查找数据结构,并且具有双向散列。它可能适合您的目的(除了学生ID顺序中的快速枚举之外,将学生ID存储在数组中没有多少收获),如果不是,它可以作为灵感。