我有一个学生姓名及其ID的列表。有时我需要使用id搜索名称,有时我需要使用名称搜索id。
array[id] = name
,则可以快速找到使用ID的名称但使用名称查找ID的速度很慢。hash{name} = id
,则可以使用名称快速找到ID,但很难从ID中找到名称。表示学生姓名关系的最佳数据结构是什么?注意:学生姓名是一个字符串,而id是从1到这些学生总数的连续整数。
感谢。
答案 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存储在数组中没有多少收获),如果不是,它可以作为灵感。