如何搜索以相同数组中的其他单词开头和结尾的单词?

时间:2010-09-01 00:53:17

标签: javascript regex arrays perl string

我在数组中有很长的单词列表。有些短,有些长。我想过滤掉那些以数组中的单词开头的单词(这个“前缀”单词的长度可以设置为3个字符),并且同时以单词结尾。

让我们说第一个词是'车棚'。现在,如果阵列中还存在'car'和'port',我会得到一个匹配。但如果这个词是'carlsberg',我就不会得到匹配(因为'lsberg'可能不会是数组中现有的单词)。

结果最好是“前缀词,后缀词,整个词”。

我会考虑使用任何可以让我这样做的语言,尽管我自己主要是一个JavaScript人。

5 个答案:

答案 0 :(得分:1)

我想知道trie是否会有所帮助,请参阅What is the most common use of the “trie” data structure?

Perl有几个模块来构建它们:

其他听起来像是起点的地方是Ruby's Abbrev模块:

#!/usr/bin/env ruby

require 'abbrev'
require 'pp'

pp %w[car port carport carlsberg].abbrev
# >> {"por"=>"port",
# >>  "po"=>"port",
# >>  "p"=>"port",
# >>  "carpor"=>"carport",
# >>  "carpo"=>"carport",
# >>  "carp"=>"carport",
# >>  "carlsber"=>"carlsberg",
# >>  "carlsbe"=>"carlsberg",
# >>  "carlsb"=>"carlsberg",
# >>  "carls"=>"carlsberg",
# >>  "carl"=>"carlsberg",
# >>  "car"=>"car",
# >>  "port"=>"port",
# >>  "carport"=>"carport",
# >>  "carlsberg"=>"carlsberg"}

答案 1 :(得分:0)

嗯,JavaScript中的天真实现是这样的:

function triples(words) { 
    var result = new Array();
    for(var i=0; i<words.length; i++) {
        for(var j=0; j<words.length; j++) {
            var k = words.indexOf(words[i] + words[j]);
            if(k != -1) {
                result.push([words[i], words[j], words[k]]);
            }
        }
    } 
    return result;
}

当前形式的函数需要所有单词的数组作为参数,并返回包含找到的单词三元组的数组数组(第一个元素是前缀,第二个元素是后缀,第三个元素是组合单词)。 / p>

答案 2 :(得分:0)

这样的事情:

#!/usr/bin/perl

use strict;
use warnings;

my @candidates=qw( carport Carsburg butterfly 
                buttercup Christmas wishlist carpface flyface buttface);
my @arr=<DATA>;
chomp @arr;

for my $i (3..6) {
    foreach my $j (@candidates) {
        my ($fp,$lp)=($1,$2) if ($j=~/(^.{$i})(.*$)/);
        if($fp && $lp) {
            my @hit1=grep(/^$fp/,@arr);
            my @hit2=grep(/$lp$/,@arr);
            print "candidate: $j\n start= @hit1 end= @hit2\n=====\n" 
                if (scalar @hit1 && scalar @hit2);
        }
    }
}

__DATA__
car
port
wish
list
Christ
mas
butter
cup
fly
face
butt

输出:

candidate: carport
 start= car end= port
=====
candidate: flyface
 start= fly end= face
=====
candidate: wishlist
 start= wish end= list
=====
candidate: buttface
 start= butter butt end= face
=====
candidate: butterfly
 start= butter end= fly
=====
candidate: buttercup
 start= butter end= cup
=====
candidate: Christmas
 start= Christ end= mas

答案 3 :(得分:0)

这是一个O(n + 2m)的Perl解决方案:

use warnings;
use strict;
use Data::Dumper;

my @words = qw(car carport carlsberg cartographer airport photographer);

my @ends  = qw(car port air grapher);

my $ends_re = join '|' => @ends;

my @matches = map {/^($ends_re).*($ends_re)$/ ? [$1, $_, $2] : ()} @words;

print Dumper \@matches;

打印:

$VAR1 = [
      [
        'car',
        'carport',
        'port'
      ],
      [
        'car',
        'cartographer',
        'grapher'
      ],
      [
        'air',
        'airport',
        'port'
      ]
    ];

答案 4 :(得分:0)

我会做类似的事情:

<?php

    $words = array('experts', 'exchange', 'expert', 'sexchange');

    // build trie
    $t = array();
    foreach ($words as $word)
    {
        $n = &$t;
        for ($i = 0; $i < strlen($word); ++$i)
        {
            $c = $word[$i];

            if (!isset($n[$c])) $n[$c] = array();

            $n = &$n[$c];
        }

        $n['.'] = true;
    }

    $word = 'expertsexchange';

    $n = $t;
    for ($i = 0; $i < strlen($word); ++$i)
    {
        $c = $word[$i];

        if (isset($n['.']))
        {
            $o = $t;
            for ($j = $i; $j < strlen($word); ++$j)
            {
                $d = $word[$j];
                if (!isset($o[$d])) break;
                $o = $o[$d];                    
            }

            # found match
            if ($j == strlen($word) && isset($o['.']))
            {
                echo substr($word, 0, $i).",".substr($word,$i).",".$word."\n";
            }
        }

        if (isset($n[$c]))
        {
            $n = $n[$c];
        }
        else
            break;
    }
?>

Results:

expert,sexchange,expertsexchange
experts,exchange,expertsexchange

我是当场写的,所以它可能无法正常工作。但我们的想法是构建一个前缀树并逐步完成它。每次找到前缀(通过'。'表示)时,再次从树顶部继续查看是否可以从该点找到后缀。假设您在前缀和后缀之间不需要任何内容​​。