检查给定字符串是否有效匹配一组前缀

发布于 2024-10-19 08:29:42 字数 453 浏览 8 评论 0原文

使用什么算法来检查给定字符串是否与一组前缀匹配,以及该组中的哪个前缀?

其他变体:给定路径和一组目录,如何检查路径是否在一组目录中(假设没有符号链接,或者它们不重要)?

我对算法的描述或名称感兴趣,或者解决这个问题的 Perl 模块(或者可以用来解决这个问题)。

编辑
允许有效查找字符串集(目录集)之间的关系的解决方案的奖励积分

例如,给定的目录集:foo、foo/bar、foo/ baz, quux, baz/quux, baz/quux/plugh 该算法是找到 foofoo/barfoo/ 的前缀baz,并且 baz/quuxbaz/quux/plugh 的前缀...希望没有 O(n^2) 时间。

What algorithm to use to check if a given string matches one of set of prefixes, and which prefix from that set?

Other variation: given path and a set of directories, how to check if path is in one of set of directories (assuming that there are no symbolic links, or they do not matter)?

I'm interested in description or name of algorithm, or Perl module which solves this (or can be used to solve this).

Edit
Bonus points for solution which allow to effectively find 'is prefix of' relation between set of strings (set of directories)

For example, given set of directories: foo, foo/bar, foo/baz, quux, baz/quux, baz/quux/plugh the algorithm is to find that foo is prefix of foo/bar and foo/baz, and that baz/quux is prefix of baz/quux/plugh... hopefully without O(n^2) time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩动你心 2024-10-26 08:29:42

执行此操作的有效方法是使用 Trie:

http://en.wikipedia.org/wiki/Trie

CPAN 上有一个包:

https://metacpan.org/pod/Tree ::Trie

(虽然我自己从未使用过该包)

您需要考虑哪些操作需要最有效。在 Trie 中进行查找非常便宜,但是如果您只为一次查找构建 trie,那么它可能不是最快的方法......

The efficient way to do this would be using a Trie:

http://en.wikipedia.org/wiki/Trie

There is a package for it on CPAN:

https://metacpan.org/pod/Tree::Trie

(never used that package myself though)

You need to consider your what operations need to be the most efficient. The lookup is very cheap in a Trie, but if you only build the trie for one lookup, it might not be the fastest way...

王权女流氓 2024-10-26 08:29:42

List::Util Core 模块中的 first 函数可以查找前缀是否与字符串匹配。它搜索前缀列表,并在找到匹配项后立即返回。如果没有必要,它不会搜索整个列表:

first 返回第一个元素
BLOCK 的结果是真值。如果
BLOCK 永远不会返回 true 或 LIST 是
空则返回 undef。

The first function in the List::Util Core module can find if a prefix matches a string. It searches through the list of prefixes, and returns as soon as it finds a match. It does not search through the whole list if it is not necessary:

first returns the first element where the
result from BLOCK is a true value. If
BLOCK never returns true or LIST was
empty then undef is returned.

大姐,你呐 2024-10-26 08:29:42

你提出了一个有趣的问题,但是当我出去寻找这样的东西时(例如在 List::MoreUtils 中),我不断地回想起,这与 有什么不同grep。这就是我基于 grep 的基本实现。如果您不介意搜索整个列表,或者想要所有匹配项,这里是一个示例:

#!/usr/bin/perl

use strict;
use warnings;

my @prefixes = qw/ pre1 pre2 pre3 /;

my $test = 'pre1fixed';
my @found = grep { $test =~ /^$_/ } @prefixes;

print "$_ is a prefix of $test\n" for @found;

我也认为必须有某种方法可以使用智能匹配运算符 ~~ 来执行此操作以短路的方式。另外,正如 toolic 指出的,List::Util 函数也可以用于此目的。这会在找到匹配项后停止搜索。

#!/usr/bin/perl

use strict;
use warnings;

use List::Util qw/first/;

my @prefixes = qw/ pre1 pre2 pre3 /;

my $test = 'pre1fixed';
my $found = first { $test =~ /^$_/ } @prefixes;

print "$found is the prefix of $test\n";

我知道的唯一算法是 Aho-Corasick将其作为练习留给读者(即我不知道),看看这是否对您有帮助。我看到有一个模块 (Algorithm::AhoCorasick)。我还相信我在某处读到过,在某些情况下,这个结构和 trie 结构是在 Perl 的匹配中实现的。也许有人知道我在哪里读到的?编辑:在关于匹配替代方案的SO问题中找到它

You pose an interesting question, but as I went out to look for such a thing (in List::MoreUtils for example), I kept coming back to, how is this any different than a grep. So here it is, my basic implementation based on grep. If you don't mind searching the whole list, or want all the matches here is an example:

#!/usr/bin/perl

use strict;
use warnings;

my @prefixes = qw/ pre1 pre2 pre3 /;

my $test = 'pre1fixed';
my @found = grep { $test =~ /^$_/ } @prefixes;

print "$_ is a prefix of $test\n" for @found;

I also I imagine that there must be some way to use the smart-match operator ~~ to do this in a short-circuiting way. Also, as toolic points out the List::Util function could be used for this too. This stops the search after a match is found.

#!/usr/bin/perl

use strict;
use warnings;

use List::Util qw/first/;

my @prefixes = qw/ pre1 pre2 pre3 /;

my $test = 'pre1fixed';
my $found = first { $test =~ /^$_/ } @prefixes;

print "$found is the prefix of $test\n";

The only algorithm I am aware of is the Aho-Corasick though I will leave it as an exercise to the reader (i.e. I don't know) to see if this will help you. I see that there is a module (Algorithm::AhoCorasick). I also believe I have read somewhere that this and trie structures are implemented in Perl's matching under certain circumstances. Perhaps someone knows where I read that? Edit: found it in SO question on matching alternatives

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文