Perl:Foreach 循环中的最终输出行打印两次
Perl: Final Output Line in Foreach Loop Prints Twice
我正在尝试编写一个非常简单的脚本,它从 STDIN 中获取两个单词,如果它们是变位词则输出 TRUE,否则输出 FALSE。我的主要问题是,如果这两个词不是变位词(这是脚本中最后的 "else" 语句),输出如下:
抱歉,这不是字谜对
抱歉,这不是字谜对
我想要的地方:
抱歉,这不是字谜对
其他更小的问题,特别慷慨:
- 我知道 Perl 的 FALSE 值是什么,但我无法让脚本打印 FALSE,例如,将变量设置为 '' 或 0 等,或者说 "return ''"。理想情况下,我根本不必在脚本中放入 "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";
}
}
在构建完 %anaHash
之后但在开始检查之前,打印出 %anaHash
的内容很有用。使用单词 "foo" 和 "bar",我使用 Data::Dumper.
得到这个结果
$VAR1 = {
'abr' => [
'bar'
],
'foo' => [
'foo'
]
};
所以哈希有两个键。当您循环散列中的所有键时,您将收到两次消息(每个键一次)。
我不太确定这里的哈希值是什么。我认为没有必要。我认为您需要:
- 读入两个字
- 将单词转换为规范格式
- 检查两个字符串是否相同
简化后,您的代码将如下所示:
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.";
}
我正在尝试编写一个非常简单的脚本,它从 STDIN 中获取两个单词,如果它们是变位词则输出 TRUE,否则输出 FALSE。我的主要问题是,如果这两个词不是变位词(这是脚本中最后的 "else" 语句),输出如下:
抱歉,这不是字谜对 抱歉,这不是字谜对
我想要的地方:
抱歉,这不是字谜对
其他更小的问题,特别慷慨:
- 我知道 Perl 的 FALSE 值是什么,但我无法让脚本打印 FALSE,例如,将变量设置为 '' 或 0 等,或者说 "return ''"。理想情况下,我根本不必在脚本中放入 "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";
}
}
在构建完 %anaHash
之后但在开始检查之前,打印出 %anaHash
的内容很有用。使用单词 "foo" 和 "bar",我使用 Data::Dumper.
$VAR1 = {
'abr' => [
'bar'
],
'foo' => [
'foo'
]
};
所以哈希有两个键。当您循环散列中的所有键时,您将收到两次消息(每个键一次)。
我不太确定这里的哈希值是什么。我认为没有必要。我认为您需要:
- 读入两个字
- 将单词转换为规范格式
- 检查两个字符串是否相同
简化后,您的代码将如下所示:
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.";
}