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

Perl: Final Output Line in Foreach Loop Prints Twice

我正在尝试编写一个非常简单的脚本,它从 STDIN 中获取两个单词,如果它们是变位词则输出 TRUE,否则输出 FALSE。我的主要问题是,如果这两个词不是变位词(这是脚本中最后的 "else" 语句),输出如下:

抱歉,这不是字谜对 抱歉,这不是字谜对

我想要的地方:

抱歉,这不是字谜对

其他更小的问题,特别慷慨:

这是脚本!很抱歉这么长 - 同样,问题出在最终 "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";    
    }
}

在构建完 %anaHash 之后但在开始检查之前,打印出 %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
}

我的最终答案,非常感谢 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.";
}