Perl Morgan和一个字符串?

时间:2015-11-09 10:31:13

标签: string algorithm perl

我正在尝试解决hackerrank上的this问题:

所以问题是:

杰克和丹尼尔是朋友。它们都像字母,特别是大写字母。 他们正在从报纸上剪下大写字母,并且每个人都将他们的信件集合存储在不同的堆栈中。 美好的一天,摩根访问了杰克和丹尼尔。他看到了他们的藏品。摩根想知道由这两个系列组成的字典最小字符串是什么。当它位于堆栈顶部时,他可以从集合中收集一封信。 此外,摩根希望使用男孩们的所有信件。集合。

这是我在Perl中的尝试:

#!/usr/bin/perl
use strict;
use warnings;
chomp(my $n=<>);
while($n>0){
    chomp(my $string1=<>);
    chomp(my $string2=<>);
    lexi($string1,$string2);
    $n--;
}
sub lexi{
   my($str1,$str2)=@_;
   my @str1=split(//,$str1);
   my @str2=split(//,$str2);
   my $final_string="";

   while(@str2 && @str1){
       my $st2=$str2[0];
       my $st1=$str1[0];
       if($st1 le $st2){
         $final_string.=$st1;
         shift @str1;
       }
       else{
          $final_string.=$st2;
          shift @str2;
       }
  }
  if(@str1){
       $final_string=$final_string.join('',@str1);
  }
  else{
       $final_string=$final_string.join('',@str2);
  }
  print $final_string,"\n";
}

示例输入:

2
JACK
DANIEL
ABACABA
ABACABA

第一行包含测试用例的数量T. 接下来的两行都有这样的格式:第一行包含字符串A,第二行包含字符串B.

示例输出:

DAJACKNIEL
AABABACABACABA

但对于 Sample test-case ,它正在为其他测试用例提供错误的结果 正确的结果 / em>的。其中一个结果不正确的案例是

1
AABAC
AACAB

它输出AAAABACCAB而不是AAAABACABC

我不知道该算法有什么问题,以及为什么它与其他测试用例失败了?

更新

根据@squeamishossifrage评论如果我添加

($str1,$str2)=sort{$a cmp $b}($str1,$str2);

无论用户输入如何,结果都相同,但测试用例仍然失败。

2 个答案:

答案 0 :(得分:1)

很少有人回答评论,所以回答:

如果两个字符匹配,您需要做的是向前看。您目前正在进行简单的匹配,并且在

的情况下
ZABB
ZAAA

你将获得ZABBZAA,因为第一场比赛Z将是le Z.所以你需要做的(一个很可能不会非常有效的天真解决方案)是只要字符串/字符匹配就一直看这样:

Z eq Z
ZA eq ZA
ZAB gt ZAA

并且在那一刻你会知道第二个字符串是你要为第一个字符弹出的字符串。

修改 你更新了排序字符串,但就像我写的你仍然需要向前看。排序将解决上面两个字符串,但这两个字符串将失败:

ZABAZA
ZAAAZB
ZAAAZBZABAZA

因为这里正确的答案是ZAAAZABAZAZB,你不能发现只是比较每个字符的字符

答案 1 :(得分:1)

问题在于你处理相同的字符。请看以下示例:

ACBA
BCAB

当面对两个相同的字符(在我的例子中为C)时,你天真地从第一个字符串中选择了一个,但这并不总是正确的。你需要展望未来打破关系。您甚至可能需要提前查看许多字符。在这种情况下,第二个字符串C之后的下一个字符低于第一个字符串的下一个字符,因此您应该首先从第二个字符串中取C

通过将字符串保留为字符串,简单的字符串比较将根据需要比较尽可能多的字符来确定要使用的字符。

sub lexi {
   my ($str1, $str2) = @_;

   utf8::downgrade($str1);  # Makes sure length() will be fast
   utf8::downgrade($str2);  # since we only have ASCII letters.

   my $final_string = "";
   while (length($str2) && length($str1)) {
      $final_string .= substr($str1 le $str2 ? $str1 : $str2, 0, 1, '');
   }

   $final_string .= $str1;
   $final_string .= $str2;
   print $final_string, "\n";
}