Perl:Foreach循环中的最终输出行打印两次

时间:2018-11-11 07:42:03

标签: perl output repeat

我正在尝试编写一个非常简单的脚本,该脚本从STDIN接收两个单词,如果它们是字谜,则输出TRUE,否则输出FALSE。我的主要问题是,如果这两个词不是字谜(这是脚本中的最后一个“ else”语句),则输出看起来像:

对不起,那不是一个字谜对 抱歉,那不是字谜对

我只想要的地方:

对不起,那不是字谜对

其他特别重要的小问题:

  • 我知道Perl的FALSE值是什么,但是我无法通过例如将变量设置为''或0等,或者说“ return””来获取打印FALSE的脚本。理想情况下,我根本不必在脚本中添加“ print TRUE / FALSE”。
  • 我在脚本中放入了最后一个elsif语句,以查看它是否会影响两次打印问题。没,现在我很好奇为什么我的m //表达式不起作用。本来应该找到对相同的对,只是其中一对比另一个具有更多的空白。

这是脚本!很抱歉,这么长的时间-问题再次出现在最后的“ else”声明中。非常感谢!

#To Run: Type start.pl on the command line.
#The script should prompt you to enter a word or phrase.
#Once you've done that, it'll prompt you for another one.
#Then you will be told if the two terms are anagrams or not.

#!/usr/bin/perl -w
use strict;

#I have to use this to make STDIN work. IDK why.

$|=1;

#variables

my $aWord;
my $bWord;
my $word;
my $sortWord;
my $sortWords;
my @words;
my %anaHash;

print "\nReady to play the anagram game? Excellent.\n\nType your first word or phrase, then hit Enter.\n\n";

$aWord = <STDIN>;
chomp $aWord;

print "\n\nThanks! Now type your second word or phrase and hit Enter.\n\n";

$bWord = <STDIN>;
chomp $bWord;

#This foreach loop performs the following tasks:

#1. Pushes the two words from STDIN into an array (unsure if this is really necessary)
#2. lowercases everything and removes all characters except for letters & spaces
#3. splits both words into characters, sorts them alphabetically, then joins the sorted letters into a single "word"
#4.pushes the array into a hash

@words = ($bWord, $aWord);
foreach $word (@words) {
    $word =~ tr/A-Z/a-z/;
    $word =~ s/[^a-z ]//ig;
    $sortWord = join '', sort(split(//, $word));
    push @{$anaHash{$sortWord}}, $word;
}

#This foreach loop tries to determine if the word pairs are anagrams or not.

foreach  $sortWords (values %anaHash) {

    #"if you see the same word twice AND the input was two identical words:"

    if (1 < @$sortWords  &&
    @$sortWords[0] eq @$sortWords[1]) {
    print "\n\nFALSE: Your phrases are identical!\n\n";
    }

    #"if you see the same word twice AND the input was two different words (i.e. a real anagram):"

    elsif (1 < @$sortWords &&
       @$sortWords[0] ne @$sortWords[1]) {
    print "\n\nTRUE: @$sortWords[0] and @$sortWords[1] are anagrams!\n\n";
    }

    #this is a failed attempt to identify pairs that are identical except one has extra spaces. Right now, this fails and falls into the "else" category below.

    elsif  (@$sortWords[0] =~ m/ +@$sortWords[-1]/ ||
        @$sortWords[-1] =~ m/ +@$sortWords[0]/) { 
    print "\n\FALSE: @$sortWords[0] and @$sortWords[-1] are NOT anagrams. Spaces are characters, too!\n\n";
    }

    #This is supposed to identify anything that's not an acronym. But the output prints twice! It's maddening!!!!
    else {
    print "Sorry, that's not an anagram pair\n";    
    }
}

2 个答案:

答案 0 :(得分:0)

完成%anaHash的内容打印后但开始检查之前,将其打印出来很有用。使用单词“ foo”和“ bar”,我使用Data::Dumper得到了这个结果。

$VAR1 = {
          'abr' => [
                     'bar'
                   ],
          'foo' => [
                     'foo'
                   ]
        };

因此散列有两个键。当您遍历哈希中的所有键时,您将收到两次消息(每个键一次)。

我不太确定这里的哈希值是什么。我认为没有必要。我认为您需要:

  1. 读两个字
  2. 将单词转换为规范格式
  3. 检查两个字符串是否相同

简化后,您的代码将如下所示:

print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2) {
  # you have an anagram
} else {
  # you don't
}

答案 1 :(得分:0)

我的最终答案,非常感谢Dave和@zdim!我很高兴我可以死。

#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?\n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?\n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~  s/[^a-z ]//ig;
$bWord =~  s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord) {
    say "\n\nFALSE: Your phrases are identical!\n";
    exit;
}

#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord) {
  say "\n\nTRUE: Your two terms are anagrams!";
}
else {
    say "\n\nFALSE: Your two terms are not acronyms.";
}