ChinaUnix首页 > 精华文章 > Perl > 正文

[精彩] 微软面世试题-最大公共串-求两个字符串的最大公共子串的一个有意思的题目


http://www.chinaunix.net 作者:iakuf  发表于:2009-03-31 17:34:57
发表评论】 【查看原文】 【Perl讨论区】【关闭

求两个字符串的最大公共子串,是一个程序员们常常考到和想到的题目,呵呵,我用perl实现了一下,听讲是当年微软面试时要求做的一个程序,写一个返回两个任意字串中最大公共串的函数,即abcdef 和 qcfbcc 返回值为bc语言不限

sub string($$){
  my ($strmin,$strmax) = @_;
       for( my $i = 0; $i < length($strmax); $i++) {
           $lstrmin = substr($strmin, $i);
           my $nowstr;
           for(my $j=0; $j< length($lstrmin);$j++){
                 my @list=split '',$lstrmin;
                 $nowstr .= @list[$j];
                 if (index($strmax, $nowstr)>=1 && length($nowstr) > length($r)){
                        $r = $nowstr;
                }

        }
    }
        return  $r;
}

修改了自己的代码,。。。呵呵,原来写的是有点问题.现在修正,晚点测试看看谁的跑的快       




对求两个字符串这种问题,好象算法蛮多的,很需要写程序的人的水平的。。。还有另一个问题,就是要是有中文怎么办

[ 本帖最后由 iakuf 于 2009-2-2 11:53 编辑 ]



 khandielas 回复于:2008-12-14 06:33:35

楼主写的象Perl写的C 程序

在Perl用hash作这些活比较典型了, 

my ($str1, $str2) = @ARGV;
my %hash1;
my %hash2;
@hash1{split '', $str1} = ();
foreach ( split '', $str2) {
if (exists $hash1{$_} && ! exists $hash2{$_}) {
print $_;
$hash2{$_} = undef;
}
}

ubuntu:~/programming/perl_prog$ ./extract_common_char.pl abcdefg mdeaafgnp
deafg

如果是用一个hash,会输出 a 俩次:  deaafg


 iakuf 回复于:2008-12-14 10:16:03

刚学习写perl,我是个菜菜


 wxlfh 回复于:2008-12-14 15:10:41

自己搞了个,班门弄斧,呵呵
sub max_mutual_str {

my($min,$max) = @_;
if (length($min)>length($max)) {
($min,$max) = ($max,$min);
}
my $len = length($min);
foreach my $rest (0..$len-1) {
foreach my $pos (0..$rest) {
my $str = substr($min,$pos,($len-$rest));
return $str if $max =~ /$str/;
}
}
return undef;
}

$str1 = '369abcdefg/789';
$str2 = '123bcdefg/0147123';
$str = max_mutual_str($str1,$str2);
print "\t$str\n";

输出
bcdefg/



 iakuf 回复于:2008-12-14 15:52:45

wxlfh写的这个非常不错啊。。。
khandielas写的其实是一个一个字符的。


 wxlfh 回复于:2008-12-14 15:55:59

最近中了正则表达式的毒,不自觉地用上了,不知道会不会有效率的问题?
见笑,见笑,呵呵。


 machine 回复于:2008-12-14 16:18:25

引用:原帖由 khandielas 于 2008-12-14 06:33 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9784912&ptid=1333575]
楼主写的象Perl写的C 程序

在Perl用hash作这些活比较典型了, 

my ($str1, $str2) = @ARGV;
my %hash1;
my %hash2;
@hash1{split '', $str1} = ();
foreach ( split '', $str2) {
        if (exists $hash ... 




这个是不是有问题?


 machine 回复于:2008-12-14 22:38:28

[table=95%][tr][td][font=FixedSys][color=#000000][color=#ff9900]#!/usr/bin/perl
[/color]#闲着没事我也写一个,呵呵
[color=#0000ff]sub[/color] max_mutual_str [color=#0000cc]{[/color]
  [color=#0000ff]my[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]str1[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]str2[/color][color=#0000cc])[/color] [color=#0000cc]=[/color] [color=#0000ff]@[/color][color=#808000]_[/color][color=#0000cc];[/color]
  [color=#0000ff]my[/color] [color=#0000ff]%[/color][color=#800000]cmp[/color][color=#0000cc];[/color]
  [color=#0000ff]my[/color] [color=#0000ff]$[/color][color=#008080]max[/color][color=#0000cc];[/color]
  [color=#0000ff]my[/color] [color=#0000ff]@[/color][color=#808000]list1[/color][color=#0000cc]=[/color][color=#ff0000]split[/color] [color=#ff00ff]''[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]str1[/color][color=#0000cc];[/color]
  [color=#0000ff]my[/color] [color=#0000ff]@[/color][color=#808000]list2[/color][color=#0000cc]=[/color][color=#ff0000]split[/color] [color=#ff00ff]''[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]str2[/color][color=#0000cc];[/color]
  [color=#0000ff]for[/color][color=#0000cc]([/color][color=#0000ff]my[/color] [color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc]=[/color]0[color=#0000cc];[/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc]<[/color][color=#0000ff]$[/color][color=#ff9900]#list1+1;$i++){
[/color]
    [color=#0000ff]for[/color][color=#0000cc]([/color][color=#0000ff]my[/color] [color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]=[/color]0[color=#0000cc];[/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]<[/color][color=#0000ff]$[/color][color=#ff9900]#list2+1;$j++){
[/color]
       [color=#0000ff]$[/color][color=#008080]cmp[/color][color=#0000cc]{[/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc].[/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]}[/color][color=#0000cc]=[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]list1[/color][color=#0000cc][[/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc]][/color] [color=#0000ff]eq[/color] [color=#0000ff]$[/color][color=#008080]list2[/color][color=#0000cc][[/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]][/color][color=#0000cc])[/color] [color=#0000cc]?[/color] [color=#0000cc]([/color]1[color=#0000cc]+[/color][color=#0000ff]$[/color][color=#008080]cmp[/color][color=#0000cc]{[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc]-[/color]1[color=#0000cc])[/color][color=#0000cc].[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]-[/color]1[color=#0000cc])[/color][color=#0000cc]}[/color][color=#0000cc])[/color] [color=#0000cc]:[/color] 0[color=#0000cc];[/color]
       [color=#0000ff]$[/color][color=#008080]max[/color][color=#0000cc]=[/color][color=#0000ff]$[/color][color=#008080]cmp[/color][color=#0000cc]{[/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc].[/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]}[/color] [color=#0000ff]if[/color] [color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]cmp[/color][color=#0000cc]{[/color][color=#0000ff]$[/color][color=#008080]i[/color][color=#0000cc].[/color][color=#0000ff]$[/color][color=#008080]j[/color][color=#0000cc]}[/color][color=#0000cc]>[/color][color=#0000ff]$[/color][color=#008080]max[/color][color=#0000cc])[/color][color=#0000cc];[/color]
       [color=#ff0000]print[/color] [color=#ff00ff]"$cmp{$i.$j}"[/color][color=#0000cc];[/color]
    [color=#0000cc]}[/color]
    [color=#ff0000]print[/color] [color=#ff00ff]"\n"[/color][color=#0000cc];[/color]
  [color=#0000cc]}[/color]
  [color=#0000ff]for[/color] [color=#0000cc]([/color][color=#ff0000]keys[/color] [color=#0000ff]%[/color][color=#800000]cmp[/color][color=#0000cc])[/color][color=#0000cc]{[/color]
      [color=#0000ff]if[/color] [color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]cmp[/color][color=#0000cc]{[/color][color=#0000ff]$[/color][color=#008080]_[/color][color=#0000cc]}[/color] [color=#0000cc]=[/color][color=#0000cc]=[/color] [color=#0000ff]$[/color][color=#008080]max[/color] [color=#0000cc])[/color][color=#0000cc]{[/color]
         [color=#0000ff]my[/color] [color=#0000ff]$[/color][color=#008080]offset[/color][color=#0000cc]=[/color][color=#ff0000]substr[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]_[/color][color=#0000cc],[/color]0[color=#0000cc],[/color]1[color=#0000cc])[/color][color=#0000cc]+[/color]1[color=#0000cc]-[/color][color=#0000ff]$[/color][color=#008080]max[/color][color=#0000cc];[/color]
         [color=#0000ff]return[/color] [color=#ff0000]substr[/color][color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]str1[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]offset[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]max[/color][color=#0000cc])[/color][color=#0000cc];[/color]
      [color=#0000cc]}[/color]
  [color=#0000cc]}[/color]
[color=#0000cc]}[/color]

[color=#0000ff]my[/color] [color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]str1[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]str2[/color][color=#0000cc])[/color] [color=#0000cc]=[/color] [color=#0000ff]@[/color][color=#808000]ARGV[/color][color=#0000cc];[/color]
[color=#0000ff]my[/color] [color=#0000ff]$[/color][color=#008080]str[/color][color=#0000cc]=[/color] max_mutual_str[color=#0000cc]([/color][color=#0000ff]$[/color][color=#008080]str1[/color][color=#0000cc],[/color][color=#0000ff]$[/color][color=#008080]str2[/color][color=#0000cc])[/color][color=#0000cc];[/color]
[color=#ff0000]print[/color] [color=#ff00ff]"$str\n"[/color][color=#0000cc];[/color]
[/color][/font][/td][/tr][/table]

[ 本帖最后由 machine 于 2008-12-14 22:39 编辑 ]


 wxlfh 回复于:2008-12-14 23:15:09

machine,你的思路不好懂啊,还是我的直观一点,简洁一点:em03: :em03: :em03:


 machine 回复于:2008-12-15 09:01:03

[font=Fixedsys][color=#0000cc][/color][/font]
我这个算法,用的是一个比较老套的lcs算法。以前用c写过,在perl下又模仿实现了一下。

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设成零,最后矩阵中最长的不为零的对角线就是最大子字串。
例如:
[table=111][tr][td] [/td][td]m [/td][td] a[/td][td]c [/td][td]h [/td][td]i [/td][/tr][tr][td]a [/td][td]0 [/td][td]1 [/td][td]0 [/td][td] 0[/td][td] 0[/td][/tr][tr][td] b[/td][td] 0[/td][td] 0[/td][td] 0[/td][td] 0[/td][td]0 [/td][/tr][tr][td] m [/td][td] [color=red]1[/color][/td][td] 0[/td][td] 0[/td][td] 0[/td][td] 0[/td][/tr][tr][td] a[/td][td] 0[/td][td] [color=red]1[/color][/td][td] 0[/td][td] 0[/td][td] 0[/td][/tr][tr][td] c[/td][td] 0[/td][td] 0[/td][td] [color=red]1[/color][/td][td] 0[/td][td] 0[/td][/tr][/table]


这样有点问题:建完矩阵还要去找最长对角线,麻烦。
解决方案是:相等时不只把矩阵元素设为“1”,而是设成它左上角的元素值加一。
例如:
[table=111][tr][td] [/td][td]m [/td][td] a[/td][td]c [/td][td]h [/td][td]i [/td][/tr][tr][td]a [/td][td]0 [/td][td]1 [/td][td]0 [/td][td] 0[/td][td] 0[/td][/tr][tr][td] b[/td][td] 0[/td][td] 0[/td][td] 0[/td][td] 0[/td][td]0 [/td][/tr][tr][td] m [/td][td] [color=red]1[/color][/td][td] 0[/td][td] 0[/td][td] 0[/td][td] 0[/td][/tr][tr][td] a[/td][td] 0[/td][td] [color=red]2[/color][/td][td] 0[/td][td] 0[/td][td] 0[/td][/tr][tr][td] c[/td][td] 0[/td][td] 0[/td][td] [color=red]3[/color][/td][td] 0[/td][td] 0[/td][/tr][/table]

所以矩阵建好后,找到矩阵中最大的元素就ok了。

上面的那个多少还有点像用perl写的c程序,下面给个更像perl程序的:
[table=95%][tr][td][font=FixedSys][color=#000000][color=#FF9900]#!perl
[/color]
[color=#0000FF]sub[/color] max_mutual_str [color=#0000CC]{[/color]
  [color=#0000FF]my[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color] [color=#0000CC]=[/color] [color=#0000FF]@[/color][color=#808000]_[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]%[/color][color=#800000]cmp[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]@[/color][color=#808000]list1[/color][color=#0000CC]=[/color][color=#FF0000]split[/color] [color=#FF00FF]''[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]@[/color][color=#808000]list2[/color][color=#0000CC]=[/color][color=#FF0000]split[/color] [color=#FF00FF]''[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC];[/color]
  [color=#0000FF]for[/color] [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]i[/color] [color=#0000CC]([/color]0[color=#0000CC].[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#FF9900]#list1){
[/color]

    [color=#0000FF]for[/color] [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]j[/color] [color=#0000CC]([/color]0[color=#0000CC].[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#FF9900]#list2){
[/color]

       [color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color][color=#0000CC]=[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]list1[/color][color=#0000CC][[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC]][/color] [color=#0000FF]eq[/color] [color=#0000FF]$[/color][color=#008080]list2[/color][color=#0000CC][[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]][/color][color=#0000CC])[/color] [color=#0000CC]?[/color] [color=#0000CC]([/color]1[color=#0000CC]+[/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC]-[/color]1[color=#0000CC])[/color][color=#0000CC].[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]-[/color]1[color=#0000CC])[/color][color=#0000CC]}[/color][color=#0000CC])[/color] [color=#0000CC]:[/color] 0[color=#0000CC];[/color]
       [color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC]=[/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color] [color=#0000FF]if[/color] [color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color][color=#0000CC]>[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC])[/color][color=#0000CC];[/color]
       [color=#FF0000]print[/color] [color=#FF00FF]"$cmp{$i.$j}"[/color][color=#0000CC];[/color]
    [color=#0000CC]}[/color]
    [color=#FF0000]print[/color] [color=#FF00FF]"\n"[/color][color=#0000CC];[/color]
  [color=#0000CC]}[/color]
  [color=#0000FF]for[/color] [color=#0000CC]([/color][color=#FF0000]keys[/color] [color=#0000FF]%[/color][color=#800000]cmp[/color][color=#0000CC])[/color][color=#0000CC]{[/color]
      [color=#0000FF]if[/color] [color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]_[/color][color=#0000CC]}[/color] [color=#0000CC]=[/color][color=#0000CC]=[/color] [color=#0000FF]$[/color][color=#008080]max[/color] [color=#0000CC])[/color][color=#0000CC]{[/color]
         [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]offset[/color][color=#0000CC]=[/color][color=#FF0000]substr[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]_[/color][color=#0000CC],[/color]0[color=#0000CC],[/color]1[color=#0000CC])[/color][color=#0000CC]+[/color]1[color=#0000CC]-[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC];[/color]
         [color=#0000FF]return[/color] [color=#FF0000]substr[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]offset[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC])[/color][color=#0000CC];[/color]
      [color=#0000CC]}[/color]
  [color=#0000CC]}[/color]
[color=#0000CC]}[/color]

[color=#0000FF]my[/color] [color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color] [color=#0000CC]=[/color] [color=#0000FF]@[/color][color=#808000]ARGV[/color][color=#0000CC];[/color]
[color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]str[/color][color=#0000CC]=[/color] max_mutual_str[color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color][color=#0000CC];[/color]
[color=#FF0000]print[/color] [color=#FF00FF]"$str\n"[/color][color=#0000CC];[/color][/color][/font][/td][/tr][/table]


 adminsinx 回复于:2008-12-15 11:05:05

引用:原帖由 khandielas 于 2008-12-14 06:33 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9784912&ptid=1333575]
楼主写的象Perl写的C 程序

在Perl用hash作这些活比较典型了, 

my ($str1, $str2) = @ARGV;
my %hash1;
my %hash2;
@hash1{split '', $str1} = ();
foreach ( split '', $str2) {
        if (exists $hash ... 




请教@hash1{split '', $str1} = ();
这句话是什么意思?


 wxlfh 回复于:2008-12-15 18:36:10

引用:原帖由 machine 于 2008-12-15 09:01 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9787939&ptid=1333575]

我这个算法,用的是一个比较老套的lcs算法。以前用c写过,在perl下又模仿实现了一下。

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设 ... 


你这个算法可能是C语言优化的,用C语言可能效率很高。


 churchmice 回复于:2008-12-15 19:31:30

引用:原帖由 machine 于 2008-12-15 09:01 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9787939&ptid=1333575]

我这个算法,用的是一个比较老套的lcs算法。以前用c写过,在perl下又模仿实现了一下。

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设 ... 


仰慕阿


 machine 回复于:2008-12-16 10:43:18

是的,这个算法我用c语言写过,效率确实不错,就是字符串大的时候建立矩阵比较占内存,还有自己清理(perl就好多了,自动清理)。现在就是不知道用perl实现起来是不是也很高效, 比 wxlfh 那个正则的算法比较那个效率更高? 高手能否帮分析一下。


 smonkey0 回复于:2008-12-16 13:24:27

有空看看生物的 blast算法。。


 machine 回复于:2008-12-17 10:47:56

今天早上看自己的博客,又看到这个代码,突然发现,当初竟然犯傻了,既然都找到最大的公共字符串了,干嘛还要在遍历一遍散列呢,真的够傻的,惭愧啊。:outu: :outu: 

[table=95%][tr][td][font=FixedSys][color=#000000][color=#FF9900]#!perl
[/color]

[color=#0000FF]sub[/color] max_mutual_str [color=#0000CC]{[/color]
  [color=#0000FF]my[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color] [color=#0000CC]=[/color] [color=#0000FF]@[/color][color=#808000]_[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]%[/color][color=#800000]cmp[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]beginning_station[/color][color=#0000CC];[/color] [color=#FF9900]#beginning station of the common string in $str1
[/color]
  [color=#0000FF]my[/color] [color=#0000FF]@[/color][color=#808000]list1[/color][color=#0000CC]=[/color][color=#FF0000]split[/color] [color=#FF00FF]''[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC];[/color]
  [color=#0000FF]my[/color] [color=#0000FF]@[/color][color=#808000]list2[/color][color=#0000CC]=[/color][color=#FF0000]split[/color] [color=#FF00FF]''[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC];[/color]
  [color=#0000FF]for[/color] [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]i[/color] [color=#0000CC]([/color]0[color=#0000CC].[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#FF9900]#list1){
[/color]


    [color=#0000FF]for[/color] [color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]j[/color] [color=#0000CC]([/color]0[color=#0000CC].[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#FF9900]#list2){
[/color]


       [color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color][color=#0000CC]=[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]list1[/color][color=#0000CC][[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC]][/color] [color=#0000FF]eq[/color] [color=#0000FF]$[/color][color=#008080]list2[/color][color=#0000CC][[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]][/color][color=#0000CC])[/color] [color=#0000CC]?[/color] [color=#0000CC]([/color]1[color=#0000CC]+[/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC]-[/color]1[color=#0000CC])[/color][color=#0000CC].[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]-[/color]1[color=#0000CC])[/color][color=#0000CC]}[/color][color=#0000CC])[/color] [color=#0000CC]:[/color] 0[color=#0000CC];[/color]
        [color=#0000FF]if[/color] [color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color][color=#0000CC]>[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC])[/color][color=#0000CC]{[/color]
           [color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC]=[/color][color=#0000FF]$[/color][color=#008080]cmp[/color][color=#0000CC]{[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC].[/color][color=#0000FF]$[/color][color=#008080]j[/color][color=#0000CC]}[/color][color=#0000CC];[/color]
           [color=#0000FF]$[/color][color=#008080]beginning_station[/color][color=#0000CC]=[/color][color=#0000FF]$[/color][color=#008080]i[/color][color=#0000CC]+[/color]1[color=#0000CC]-[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC];[/color]
         [color=#0000CC]}[/color]
       [color=#FF0000]print[/color] [color=#FF00FF]"$cmp{$i.$j}"[/color][color=#0000CC];[/color]
    [color=#0000CC]}[/color]
    [color=#FF0000]print[/color] [color=#FF00FF]"\n"[/color][color=#0000CC];[/color]
  [color=#0000CC]}[/color]

  [color=#0000FF]return[/color] [color=#FF0000]substr[/color][color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]beginning_station[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]max[/color][color=#0000CC])[/color][color=#0000CC];[/color]

[color=#0000CC]}[/color]

[color=#0000FF]my[/color] [color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color] [color=#0000CC]=[/color] [color=#0000FF]@[/color][color=#808000]ARGV[/color][color=#0000CC];[/color]
[color=#0000FF]my[/color] [color=#0000FF]$[/color][color=#008080]str[/color][color=#0000CC]=[/color] max_mutual_str[color=#0000CC]([/color][color=#0000FF]$[/color][color=#008080]str1[/color][color=#0000CC],[/color][color=#0000FF]$[/color][color=#008080]str2[/color][color=#0000CC])[/color][color=#0000CC];[/color]
[color=#FF0000]print[/color] [color=#FF00FF]"$str\n"[/color][color=#0000CC];[/color][/color][/font][/td][/tr][/table]


 DQP 回复于:2008-12-17 14:26:54

引用:原帖由 machine 于 2008-12-15 09:01 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9787939&ptid=1333575]

我这个算法,用的是一个比较老套的lcs算法。以前用c写过,在perl下又模仿实现了一下。

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设 ... 



不得不赞一个


 MMMIX 回复于:2008-12-17 14:36:01

引用:原帖由 adminsinx 于 2008-12-15 11:05 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9788839&ptid=1333575]



请教@hash1{split '', $str1} = ();
这句话是什么意思? 


见 perldata 中的 Slices


 iakuf 回复于:2008-12-19 21:44:04

sub string($$){
   ($strmin,$strmax) = @_;
       for( my $i = 0; $i < length($strmax); $i++) {
           $lstrmin = substr($strmin, $i);
           for(my $j=0; $j< length($lstrmin);$j++){
                chop($lstrmin);
                if (index($strmax, $lstrmin)>=1 && length($lstrmin) > length($r)){
                        $r = $lstrmin;
                }

            }
    }
        return  $r;
}


第4次改进


 lzs45 回复于:2008-12-19 22:25:01

引用:原帖由 machine 于 2008-12-15 09:01 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9787939&ptid=1333575]

我这个算法,[color=Blue]用的是一个比较老套的lcs算法[/color]。以前用c写过,在perl下又模仿实现了一下。

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设 ... 



呵呵,学习,还是第一次见这个算法


 bandaotidejia 回复于:2008-12-26 13:53:54

微软还用perl?

面试 面世


 iakuf 回复于:2008-12-26 21:21:09

人家当时的要求是,无论你用什么方法来写


 mfzz1134 回复于:2008-12-27 01:13:51

经典DP,开矩阵是对地,效率最高.


 wxlfh 回复于:2008-12-28 10:30:10

Perl中可能效率不是最高也说不定。


 cheveu 回复于:2009-01-02 13:36:12

我是外行,不会编程。
不过,不知道“卷积”可行不?


 junonly 回复于:2009-01-05 22:48:50

perl 新手, 写个试试

#!/usr/bin/perl

&max_index_of_two_string('xabcdxxxveafa', 'eabcafeveafaeagagade');

sub max_index_of_two_string()
{
    my ($str1, $str2) = @_;
    my $max_index_of_two_string = undef;
    if (length($str1) < length($str2)) { 
        my $str = $str1;
        $str1 = $str2;
        $str2 = $str;
    }
    my $mark = 2;
    while (length($str2) > 0) {
        while ($mark <= length($str2)) {
            my $pattern = substr($str2, 0, $mark);
            if ($str1 =~ /$pattern/) { 
                if (length($pattern) > length($max_index_of_two_string)) {
                    $max_index_of_two_string = $pattern;
                }
            }
            $mark++;
        }
        if ($str2 =~ /(.)(.*)/) {
            $str2 = $2;
            $mark = 2;
        }
    }
    print $max_index_of_two_string;
}



 machine 回复于:2009-01-06 10:36:50

my $str = $str1;
        $str1 = $str2;
        $str2 = $str;
标准c语言写法。
perl 写法:
($str1,$str2)=($str2,$str1);


 junonly 回复于:2009-01-06 12:06:51

引用:原帖由 machine 于 2009-1-6 10:36 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9903046&ptid=1333575]
my $str = $str1;
        $str1 = $str2;
        $str2 = $str;
标准c语言写法。
perl 写法:
($str1,$str2)=($str2,$str1); 


这样就可以swap了,又学到新东西啊。


 grubbyoo 回复于:2009-03-11 16:49:48

俺用 sql 写一个  oracle10g

 select  max( replace ( sys_connect_by_path(a.t, '.'),'.') ) keep (dense_rank first order by level desc  )
   from (select rownum n, substr('abcdefg1234<*>', rownum, 1) t
           from dual
         connect by rownum <= length('abcdefg1234<*>')) a,
        
        (select rownum m, substr('12345defg1237123', rownum, 1) t
           from dual
         connect by rownum <= length('12345defg1237123')) b
  where a.t = b.t
 connect by a.n = prior a.n + 1
        and b.m = prior b.m + 1


 dream3401 回复于:2009-03-11 21:43:10

引用:原帖由 iakuf 于 2008-12-14 00:37 发表 [url=http://bbs3.chinaunix.net/redirect.php?goto=findpost&pid=9784818&ptid=1333575]
回复1楼的:
sub string($$){
  my ($strmin,$strmax) = @_;
       for( my $i = 0; $i < length($strmax); $i++) {
           $lstrmin = substr($strmin, $i);
           my $nowstr;
           for(my $j=0; $j< length($lstrmin);$j++){
                 my @list=split '',$lstrmin;
                 $nowstr .= @list[$j];
                 if (index($strmax, $nowstr)>=1 && length($nowstr) > length($r)){
                        $r = $nowstr;
                }

        }
    }
        return  $r;
}



这个算法是从少到多的找,最好是从多到少的找,最长的即为最匹配的,你楼下的用正则的就是从最长开始找起,找到即是最长的.
所以我改了一下你的程序
sub mystring{
  my ($lstrmin,$r)=("","");
  my ($strmin,$strmax) = @_;
       for( my $i = 0; $i <length([color=Blue]$strmin[/color]); $i++) {
           $lstrmin =substr($strmin,$i);
           my $nowstr;
           for(my $j=[color=Blue]length($lstrmin)[/color]; $j[color=Blue]>length($r)[/color];[color=Blue]$j--[/color]){
                 [color=Blue]$nowstr =substr($lstrmin,0,$j);[/color]
                [color=Red]# print $nowstr;[/color]
                 if (index($strmax, $nowstr)>=1 && length($nowstr) > length($r)){
                        $r = $nowstr;
                        [color=Blue]last;[/color]     
           }

        }
    }
        return  $r;
}

当然用到length函数的可以先定义一个标量,这样不会每次循环时都调用length.
你可以在你写的子例程里加入红色的print $nowstr,然后比较看一下我改的,可以发现到两个字符串很长的时候循环次数的差别.

你楼下的用正则的循环次数最少.
以上供参考


 surfybeach 回复于:2009-03-12 06:34:54

或者可以读读cpan模块 [u][url=http://search.cpan.org/perldoc?Algorithm::Diff]Algorithm::Diff[/u] 的源码,函数LCS就是干这个的,求最长公共子串。

[ 本帖最后由 surfybeach 于 2009-3-12 06:39 编辑 ]


 xiaojao 回复于:2009-03-31 17:34:57

引用:原帖由 wxlfh 于 2008-12-14 15:10 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=9785738&ptid=1333575]
自己搞了个,班门弄斧,呵呵
sub max_mutual_str {
        my($min,$max) = @_;
        if (length($min)>length($max)) {
                ($min,$max) = ($max,$min);
        }
        my $len = length($min);
        foreach my $rest (0..$len-1 ... 


有个不算BUG的BUG,当有两个都符合条件时,只能求出其中一个字符串,比如:
my $str1 = '123456abcd';
my $str2 = '234dddabc';
只能求出:234,而不能求出abc




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=1333575
转载请注明作者名及原文出处