Efficient string search data structure for prefix-based operations
package Trie;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = {
children => {},
is_end_of_word => 0
};
bless $self, $class;
return $self;
}
sub insert {
my ($self, $word) = @_;
my $current = $self;
for my $char (split //, lc($word)) {
if (!exists $current->{children}->{$char}) {
$current->{children}->{$char} = Trie->new();
}
$current = $current->{children}->{$char};
}
$current->{is_end_of_word} = 1;
}
sub search {
my ($self, $word) = @_;
my $current = $self;
for my $char (split //, lc($word)) {
if (!exists $current->{children}->{$char}) {
return 0;
}
$current = $current->{children}->{$char};
}
return $current->{is_end_of_word};
}
sub starts_with {
my ($self, $prefix) = @_;
my $current = $self;
for my $char (split //, lc($prefix)) {
if (!exists $current->{children}->{$char}) {
return 0;
}
$current = $current->{children}->{$char};
}
return 1;
}
sub get_words_with_prefix {
my ($self, $prefix) = @_;
my $current = $self;
my @results = ();
# Navigate to prefix node
for my $char (split //, lc($prefix)) {
if (!exists $current->{children}->{$char}) {
return @results;
}
$current = $current->{children}->{$char};
}
# Collect all words from this point
$self->_collect_words($current, $prefix, \@results);
return @results;
}
sub _collect_words {
my ($self, $node, $prefix, $results) = @_;
if ($node->{is_end_of_word}) {
push @$results, $prefix;
}
for my $char (keys %{$node->{children}}) {
$self->_collect_words($node->{children}->{$char}, $prefix . $char, $results);
}
}
# Example usage
package main;
my $trie = Trie->new();
# Insert words
my @words = qw(cat car card care careful carry case cast);
for my $word (@words) {
$trie->insert($word);
}
print "Words inserted: " . join(", ", @words) . "\n";
# Search tests
my @search_tests = qw(car card careless);
for my $word (@search_tests) {
my $found = $trie->search($word) ? "found" : "not found";
print "Search '$word': $found\n";
}
# Prefix tests
my @prefix_tests = qw(car cas cat);
for my $prefix (@prefix_tests) {
my $exists = $trie->starts_with($prefix) ? "exists" : "doesn't exist";
print "Prefix '$prefix': $exists\n";
my @words_with_prefix = $trie->get_words_with_prefix($prefix);
if (@words_with_prefix) {
print " Words with prefix '$prefix': " . join(", ", @words_with_prefix) . "\n";
}
}
Views
Lines
Characters
Likes