【问题标题】:perl - searching a large /sorted/ array for index of a stringperl - 在大型 /sorted/ 数组中搜索字符串的索引
【发布时间】:2017-08-28 09:56:06
【问题描述】:

我有一个大约 100,000 个项目的大数组和一个大约 1000 个项目的小数组。我需要在大数组中搜索小数组中的每个字符串,并且需要返回字符串的 index。 (所以我需要搜索 100k 数组 1000 次)

大数组已经过排序,所以我猜某种二进制类型的搜索会比使用 foreach 循环(找到时使用'last'来打破循环)更有效,这就是我开始的方式。 (第一次尝试进行了大约 3000 万次比较!)

是否有内置的搜索方法可以产生更有效的结果,还是我必须手动编写二进制搜索代码?我也想避免使用外部模块。

出于问题的目的,假设我需要在大型排序数组中找到单个字符串的索引。 (我只提到 1000 个项目是为了了解规模)

【问题讨论】:

  • 为什么要避免使用外部模块?并不是说我知道一个完全符合要求的,但你可以试试tcgrep -1F,看看它是否足够快,然后修改它以返回索引;我没有寻找其他 CPAN 模块。
  • 还有List::BinarySearch。在实现你自己的任何东西之前,我会尝试使用模块。
  • 该数组是否已经在 Perl 数组中,还是存储在磁盘上?在后一种情况下,它会舒适地融入您的主记忆吗?如果没有,最好不要一次将其全部拉入主内存,即使这排除了二分搜索。
  • 您要搜索的字符串会完全匹配吗?或者它们可能是大型数组条目的子字符串?

标签: arrays perl


【解决方案1】:

这听起来像是经典的哈希用例场景,

my %index_for = map { $large_array[$_] => $_ } 0 .. $#large_array;

print "index in large array:", $index_for{ $small_array[1000] };

【讨论】:

  • 如果我只想在大数组中找到字符串“bob”的索引,那该怎么做呢?
  • @jxm $index_for{"bob"}bob 周围的引号是可选的)
【解决方案2】:

在这里使用二分搜索可能是最佳选择。二分查找只需要 O(log n) 次比较(这里 ~ 每次查找 17 次比较)。

或者,您可以创建一个将项目映射到其索引的哈希表:

my %positions;
$positions{ $large_array[$_] } = $_ for 0 .. $#large_array;

for my $item (@small_array) {
  say "$item has position $positions{$item}";
}

虽然现在每个查找都可以在 O(1) 中进行而无需任何比较,但您必须首先创建哈希表。这可能会也可能不会更快。请注意,哈希只能将字符串用作键。如果您的项目是具有自己相等概念的复杂对象,则您必须首先派生一个合适的密钥。

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 2011-02-24
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2011-07-04
    相关资源
    最近更新 更多