从散列中添加值

时间:2016-10-19 02:36:45

标签: arrays perl hash key

我正在尝试从哈希中添加密钥以从添加的值中获取总计。

这是我到目前为止所拥有的。感谢帮助。

print "What is your name?\n";
$letters = <STDIN>;

%alphabet = {
   a=>1, b=>2, c=>3, d=>4, e=>5, f=>6, g=>7, h=>8, 
   i=>9, j=>10, k=>11, l=>12, m=>13,n=>14, o=>15, 
   p=>16, q=>17, r=>18, s=>19, t=>20, u=>21, v=>22, 
   w=>23, x=>24, y=>25, z=>26
};

@characters = split('', $letters);
@$characters = keys (%alphabet);

foreach @$character {
   $starting_total = 0;
   $total = $starting_total + @$character - 10;
   print "$total\n";
};

4 个答案:

答案 0 :(得分:1)

  

我正在尝试从哈希中添加密钥以从添加的值中获取总计。

我不认为你是。哈希中的键是字母。你不能(明智地)将信件加在一起。我想你正在尝试将哈希值与一系列密钥相匹配。

准确性和精确度是程序员的重要特征。如果你无法准确,准确地描述你的问题,那么你几乎没有机会解决它。

您的代码甚至无法编译。我们来看看吧。

# You should always start your Perl programs with "use strict"
# and "use warnings".
print "What is your name?\n";
# When you "use strict" you will need to declare all of your variables
# using "my". So "my $letters = <STDIN>"
$letters = <STDIN>;

# Similarly, "my %alphabet = ..."
# But there are far better ways to set up this hash, as we'll see
# later.
# Also (as Borodin points out in a comment) you have initialised this 
# hash incorrectly. A hash should be initialised with a list:
# %alphabet = (a => 1, ...);
# Note the round parentheses indicating a list.
# You have initialised your hash with a single-element list containing
# a hash reference - braces { ... } are the anonymous hash constructor
# and they return a reference to the new hash.
# This is an error that would have been picked up by "use warnings".
%alphabet = {
   a=>1, b=>2, c=>3, d=>4, e=>5, f=>6, g=>7, h=>8, 
   i=>9, j=>10, k=>11, l=>12, m=>13,n=>14, o=>15, 
   p=>16, q=>17, r=>18, s=>19, t=>20, u=>21, v=>22, 
   w=>23, x=>24, y=>25, z=>26
};

# "my @characters ..."
@characters = split('', $letters);
# But you're also using an array reference called $characters.
# That's bound to confuse you at some point in the future
@$characters = keys (%alphabet);

# This is the bit that doesn't compile. It should be
# "foreach (@character)". But that's also not right as it uses
# an array called @character, and you don't have an array called
# @character (you have an array called @characters). "use strict"
# will catch errors like this.
# Also, each time round this loop, one of the elements from @character
# will be put into $_. But you don't use $_ in your code at all.
foreach @$character {
   # Do you really want to set this to 0 each time?
   $starting_total = 0;
   # @$character is the number of elements in the array referenced
   # by $character. Which is zero as you don't have an array
   # reference called $character. I assume you meant @$characters,
   # but that is always going to be 26 - which doesn't seem useful.
   # And why subtract 10?
   $total = $starting_total + @$character - 10;
   print "$total\n";
}

你对这个问题的描述非常模糊,但看着你的代码(并猜测了很多)我认为你要做的是:

  • 获取用户名称
  • 将名称拆分为单个字母
  • 将每个字母编码为数字(a = 1,b = 2,...,z = 26)
  • 汇总名称中的字母

我将如何做到这一点。

#/usr/bin/perl

use strict;
use warnings;
# We use modern Perl, specifically say()
use 5.010;

print 'What is your name? ';
chomp(my $name = <STDIN>);

my %letters;
@letters{'a' .. 'z'} = (1 .. 26);

my $total;

foreach (split //, $name) {
  $_ = lc $_; # force lower case
  next unless exists $letters{$_}; # ignore non-letters
  $total += $letters{$_};
}

say "$name is $total";

答案 1 :(得分:1)

此程序将按您的要求执行

它不是使用split,而是应用全局正则表达式来查找字符串中的所有字母字符。对lc的调用使每个字母小写与哈希键匹配

use strict;
use warnings 'all';

my %alphabet = (
   a =>  1, b =>  2, c =>  3, d =>  4, e =>  5, f =>  6, g =>  7, h =>  8, 
   i =>  9, j => 10, k => 11, l => 12, m => 13, n => 14, o => 15, 
   p => 16, q => 17, r => 18, s => 19, t => 20, u => 21, v => 22, 
   w => 23, x => 24, y => 25, z => 26
);

print 'What is your name? ';
my $name = <>;

my $total = 0;

while ( $name =~ /([a-z])/gi ) {
    my $letter = $1;
    my $n = $alphabet{lc $letter};
    printf "%s %2d\n", $letter, $n;
    $total += $n;
}

printf "Total %d\n", $total;

输出

What is your name? Kokio
K 11
o 15
k 11
i  9
o 15
Total 61

请注意,不需要哈希来计算字母表中字母的索引。你可以对字母的代码点进行算术运算,比如

my $n = 1 + ord(lc $letter) - (ord 'a');

或者您可以声明一个常量字符串ALPHABET,然后使用index来查找其中每个字符的位置

use constant ALPHABET => join "", 'a' .. 'z';

my $n = 1 + index ALPHABET, lc $letter;

这些替代方案产生与上述解决方案完全相同的结果,并且不需要哈希

答案 2 :(得分:0)

我不知道你到底想要什么。我添加了脚本,它添加了字符位置

print "Enter your name: ";

chomp (my $name = <STDIN>);

my @arc = split('',$name);

my $total;

my $lc_offset = ord("a") - 1;

foreach (@arc)
{

    $total+=(ord(lc($_))) - $lc_offset;

}

print $total;

无需将字母的位置存储在哈希中。因为perl具有内置功能ord。所以小写字母从97开始。

答案 3 :(得分:0)

你的问题很不清楚,所以我猜你想得到一个单词中所有字母的数字和。

#!/usr/bin/perl

use strict;
use warnings;
use constant ORD_LC_OFFSET => ord('a') - 1;

print "What is your name?\n";
chomp (my $name = <STDIN>);

my $sum = 0;
$sum += ord( lc($_) ) - ORD_LC_OFFSET for grep { m/[a-zA-Z]/ } split '', $name;
print "$sum\n";

我们split字符的名称和grep字母字符。然后我们将每个字符转换为字母的索引(ord执行魔术并将字母转换为它的ASCII值)。现在我们将其添加到$sum