免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: iakuf
打印 上一主题 下一主题

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

论坛徽章:
0
31 [报告]
发表于 2009-03-12 06:34 |只看该作者
或者可以读读cpan模块 Algorithm::Diff 的源码,函数LCS就是干这个的,求最长公共子串。

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

论坛徽章:
0
32 [报告]
发表于 2009-03-31 17:34 |只看该作者
原帖由 wxlfh 于 2008-12-14 15:10 发表
自己搞了个,班门弄斧,呵呵
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

论坛徽章:
0
33 [报告]
发表于 2010-05-27 14:33 |只看该作者
回复 1# iakuf
  1. #!/usr/bin/perl -w
  2. #求两字符串最大公共串
  3. use strict;
  4. use 5.010;
  5. my $str_1 = "abefdh";
  6. my $str_2 = "jfdjjabe";
  7. my $i = 0;
  8. my $j;
  9. my $len_1 = rindex $str_1."\$","\$";
  10. my @result;
  11. my $max = 0;
  12. while ($i<$len_1) {
  13.     $j = $len_1-1;
  14.     while ($j>=$i) {
  15.         my $sub = substr($str_1,$i,$j-$i+1);
  16.         if (index($str_2,$sub) != -1) {
  17.             my $tmp = rindex $sub."\$","\$";
  18.             if ($tmp > $max) {
  19.                 pop @result;
  20.                 push @result,$sub;
  21.                 $max = $tmp;
  22.                 last;
  23.             } elsif ($tmp == $max) {
  24.                 push @result,$sub;
  25.                 last;
  26.             } else {
  27.                 1;
  28.             }
  29.         }
  30.         $j--;
  31.     }
  32.     $i++;
  33. }
  34. print "@result\n";
复制代码

论坛徽章:
0
34 [报告]
发表于 2010-05-27 15:26 |只看该作者
本帖最后由 iamlimeng 于 2010-05-27 15:35 编辑

开始理解错误,纠正一下。

论坛徽章:
1
未羊
日期:2014-09-08 22:47:27
35 [报告]
发表于 2010-05-27 16:33 |只看该作者
有个不算BUG的BUG,当有两个都符合条件时,只能求出其中一个字符串,比如:
my $str1 = '123456abcd';
...
xiaojao 发表于 2009-03-31 17:34



    的确,我这个东西很不成熟。

论坛徽章:
0
36 [报告]
发表于 2010-05-27 16:58 |只看该作者
我开始也是有这个疑惑,若有多个公共子串,应该如何计算。我在wxlfh代码基础上改了一下,能获得长度大于2的公共子串:
  1. #!/usr/bin/perl

  2. sub max_mutual_str {
  3.         my($min,$max) = @_;
  4.         if (length($min)>length($max)) {
  5.                 ($min,$max) = ($max,$min);
  6.         }
  7.         my $len = length($min);
  8.         my $result;
  9.          my $pos = 0;
  10.          while ($pos < $len-1) {
  11.                  my $rest = $len-$pos;
  12.                   my $check = 0;
  13.                   while ($rest > 1) {
  14.                            my $str = substr($min,$pos,$rest);
  15.                            print "$pos $rest $str\n";
  16.                            if ($max =~ /$str/) {
  17.                                     $result .= " $str";
  18.                                     my $skip = length($str);
  19.                                     $pos += $skip;
  20.                                     $rest -= $skip;
  21.                                     $check = 1;
  22.                            }
  23.                            else { $rest--; }
  24.                            select(undef,undef,undef,0.05);
  25.                   }
  26.                   $pos++ if (!$check);
  27.         }
  28.         if ($result) { return($result); }
  29.         else { return("Mutual String Not Found!"); }
  30. }

  31. my $str1 = '123456abcdefeeeee';
  32. my $str2 = '234dddabcdegeeee';
  33. $str = max_mutual_str($str1,$str2);
  34. print "$str\n";
复制代码
输出:234 abcde eeee

我加了显示计算过程的代码。以上代码可能不够简洁,等高手指点。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
37 [报告]
发表于 2010-05-27 17:41 |只看该作者
本帖最后由 blackold 于 2010-05-28 09:54 编辑
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my $str1 = ...;
  5. my $str2 = ...;
  6. my $str = $str1 . "\n" . $str2;

  7. my @substr = sort { length($b) <=> length($a) } $str =~ /(.+)(?=.*\n.*\1)/g;
  8. my @result = grep { length == length $substr[0] } @substr;
  9. print "@result\n";
复制代码

论坛徽章:
0
38 [报告]
发表于 2010-05-27 23:33 |只看该作者
回复 37# blackold


这个代码太帅了。

可能需要小改一下,输出很接近正确结果了,但还得不到完全正确的结果。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
39 [报告]
发表于 2010-05-28 09:37 |只看该作者
回复 38# iamlimeng


    代码不规范,结果应该是对的(假设字符串不包含\n)啊?

论坛徽章:
0
40 [报告]
发表于 2010-05-28 09:43 |只看该作者
回复 39# blackold


my $str1 = 'dddabd123456abcdefeeeee';
my $str2 = '234dddabcdegeeee';

输出:
dddab
abcde

末尾的eeee没有输出

LZ再调试一下程序。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP