免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 无风之谷
打印 上一主题 下一主题

ChinaUnix技术实践之三——Perl编程大赛 [复制链接]

论坛徽章:
0
61 [报告]
发表于 2011-03-02 19:11 |只看该作者
第2题:结果是undef。列表位于标量上下文返回最后一个元素。()可以用来创建一个空列表,也常用来清空一个列表。

第4题:$x[1]和@x[1]的结果相同,都是7。前者都知道是数组中元素的表示方法。但后者这种写法没见过,感觉应该是之前版本的写法?

论坛徽章:
0
62 [报告]
发表于 2011-03-02 23:19 |只看该作者
#1
  1. sub myfunc {
  2.     # $x = ...;
  3.     $x ? 1 : undef;
  4. }
复制代码
#2
1. $x = ()的结果是undef

2.列表在标量上下文返回其中最后一个变量或直接量在标量上下文的返回值。好像很绕口,解释一下。
主要是列表中若有数组或哈希作为它的元素的问题,在标量上下文,列表中若有数组或哈希,该数组或哈希不会平坦化,而是当成单个的元素。若处在列表最后一个元素的位置,就返回该数组或哈希在标量上下文的返回值(数组为元素个数,哈希为0或3/8这样的键/桶值)
所以@array = qw/a b c/; $s = (1,2,@array);这样返回的是3(@array的元素个数),而不是c。所以严格点说,返回的是最后一个元素的标量值,而不是最后一个元素。
把列表放到标量上下文去通常不是good practice,因为这相当于我费半天劲写了前面的元素,最后只要最后一个元素的标量值,如果use warnings了,会出现void context的警告

3. ()如果是在列表上下文,比如@a = ();那么它就是为了创建空列表或者空哈希%h = ()。如果是在标量上下文,不是纯粹为了玩儿的话,它的目的应该是为了强制给予列表上下文。比如说
  1. @a = qw/a b/;
  2. @b = qw/1 2 3 4/;
  3. @c = qw/d e f/;
  4. $s = (@a, @b, @c);
  5. print $s; # 得到3,即列表最后元素@c在标量上下文的值
复制代码
如果倒数第二行改成
  1. $s = () = (@a, @b, @c);
  2. print $s; # 得到9
复制代码
中间的()实际相当于给了后面的列表一个列表上下文,让它把@a、@b、@c都摊开,赋值给一个匿名数组,并立刻将这个匿名数组在标量上下文的值返回给$s(9就是@a、@b、@c全部元素的值)
另以splice举例,In list context, returns the elements removed from the array. In scalar context, returns the last element removed.
如果我想得到的既不是移除的元素数组,也不是最后一个元素,而是它移除的元素个数
笨的方法是先用一个临时数组接移除的元素,再把这个临时数组赋值给标量
  1. @foo = splice @array, 3;
  2. $count = @foo;
复制代码
但实际只要一行,不用引入新变量即可达到目的
  1. $count = () = splice @array, 3;
复制代码
#3
(1..3,5..

#4
$x[1]是@x的第二个元素
@x[1]是@x的第二个元素构成的一个单元素数组切片

#5
  1. @sorted = sort { -M($a) <=> -M($b) } glob "*";
复制代码
#6
  1. $sum += $_ foreach @nums;
  2. $average = $sum / @num;
  3. @above_average = grep {$_ > $average } @nums;
复制代码
#7
  1. my $secret_num = int(1 + rand 100);
  2. while (1) {
  3.     print "please input num('quit' or 'exit' to quit): ";
  4.     my $get_num = <STDIN>;
  5.     last if $get_num =~ /quit|exit|^\s*$/i;
  6.     $result = $get_num <=> $secret_num;
  7.     if ($result == 0) {
  8.         print "yes!";
  9.         last;
  10.     }
  11.     elsif ($result == -1) {
  12.         print "too low\n";
  13.     }
  14.     else {
  15.         print "too high\n";
  16.     }
  17. }
复制代码
#8
完全不会,没这需求...

论坛徽章:
0
63 [报告]
发表于 2011-03-02 23:46 |只看该作者
第三题会错意了,重写
  1. @num = (1,2,3,5,6,7,8,12,14,15,16,17,18,20);
  2. @string = @num;
  3. foreach (0..$#num) {
  4.     if ( ($num[$_] == $num[$_-1]+1) and ($num[$_] == $num[$_+1]-1) ) {
  5.         $string[$_] = "-";
  6.     }
  7. }
  8. $str = join ",", @string;
  9. $str =~ s/,(-,)+/-/g;
  10. print $str;
复制代码

论坛徽章:
0
64 [报告]
发表于 2011-03-03 19:22 |只看该作者
{:3_191:}好久没有写了,生疏了:


  1. 第一题:sub myfunc {
  2.     # $x = ...;

  3.     if ( $x ) {
  4.         return 1;
  5.     } else {
  6.         return;
  7.     }
  8. }
  9. 答:精简为:
  10. sub myfunc{
  11.     $x?return 1:return;
  12. }


  13. 第二题:
  14. $x=()结果是什么?列表位于标量上下文是什么情况?()是不是用来创建空的list?请解释原因。
  15. 答:
  16. $x=()设置为undef,这句可以清空$x中存放的引用值、对象等等,一般用来释放
  17. 列表位于标量上下文返回是元素个数
  18. ()可以用来创建空的list, ((),(),())=()



  19. 第三题:1,2,3,5,6,7,8 如何合并成1-3,5-8?
  20. 答:
  21. my @array=(1,2,3,5,6,7,8);
  22. my $head=shift @array;
  23. my $mid=$head;
  24. my @resume;
  25. while (@array){
  26.     my $x=shift @array;
  27.     if ($x-1==$mid){
  28.          $mid=$x;
  29.      }else{
  30.         push @resume,$head."-".$mid;
  31.         $head=$x;
  32.         $mid=shift @array;
  33.     }
  34.          push @resume,$head."-".$x  unless (@array);
  35. }
  36.   print join(",", @resume);

  37.    
  38. 第四题:@x=(5,7,9); $x[1]与@x[1]的区别是什么?
  39. 答:
  40. $x[1]是指 @x数组中第二个元素,返回是一个值
  41. @x[1]是包含数组片段  $x[1]的数组,返回的是个数组



  42. 第五题: 用最短和优的perl代码对当前目录下的文件和子目录按修改时间进行排序。

  43. print join "\n", ( sort {(-M $a)<=>(-M $b)} grep{ $_ ne ".."} (glob("*"),glob(".?*")));


  44. 第六题  传入一串数字并返回所有大于平均值的数字。
  45. 答:
  46. my @k=split ",",shift;
  47. my $resume;
  48. my $n=0;
  49. foreach my $i(@k){
  50.     $n++;
  51.     $resume=$resume+$i;
  52. }
  53. $resume=$resume/$n;
  54. my @rr=grep { $_ >$resume} @k;
  55. print Dumper \@rr;


  56. 第七题:
  57. 答:
  58. my ($k,$i);
  59. print "please input the number:";
  60. while  ($i=<STDIN>){

  61.     chomp $i;
  62.     $k=int(1+rand 100);
  63.     print "the randam is $k \n";
  64.     exit  if ($i eq "quit") or ($i eq "exit") or ($i =~/^\s+$/);
  65.     next  if ($i !~/\d+/);
  66.      $i>$k? print "too high\n": print "too low\n";
  67.     print "right, you are hero~\n";exit if $i== $k;
  68.     next;
  69. }
复制代码

论坛徽章:
0
65 [报告]
发表于 2011-03-03 19:22 |只看该作者
本帖最后由 chenzq1604 于 2011-03-17 00:52 编辑

第八题


  1. use strict;
  2. use POE qw{
  3. Component::Server::TCP
  4. };

  5. use constant PORT        => 7777;

  6. main();

  7. our %Sessions;

  8. sub main {

  9.    go_daemon();
  10.    start();
  11.    POE::Kernel->run();
  12.    exit(0);
  13. }

  14. sub start {
  15.    POE::Session->create(
  16.        inline_states => {
  17.        start => \&go_start,
  18.        hup_sig => \&go_hup,
  19.        }
  20.    );

  21.    POE::Component::Server::TCP->new(
  22.        Alias              => 'daemon',
  23.        Address            => "localhost",
  24.        Port               => PORT,
  25.        ClientInput        => \&client_input,
  26.        },
  27.    );
  28. }
  29. sub go_hup {
  30.   $_[HEAP]->{stop}='HUP';
  31.   $_[KERNEL]->sig_handled();
  32.    go_stop();
  33.    go_start();
  34. }

  35. sub go_start {
  36.      $_[KERNEL]->alias_set('daemon');
  37.      $_[KERNEL]->sig( HUP => 'sig_HUP');
  38. }


  39. sub go_stop {
  40.    my ($kernel, $heap, $sender) = @_[ KERNEL, HEAP, ARG0 ];
  41.    if ($heap->{stop_client_handler}) {
  42.        $kernel->post($heap->{stop_client_handler}, 'response', 'OK:stop')
  43.          if ref($heap->{stop_client_handler});
  44.        delete $heap->{stop_client_handler};
  45.    } else {
  46.        $heap->{stop_client_handler} = $sender || 1;
  47.        stop_module($kernel);
  48.        $heap->{check_result} = 'stop';
  49.    }
  50. }

  51. sub restart {
  52.    my ($kernel, $heap, $sender) =
  53.      @_[ KERNEL, HEAP, ARG0 ];
  54.    if ($heap->{restart_client_handler}) {
  55.        $kernel->post($heap->{restart_client_handler}, 'response', 'OK:restart')
  56.          if ref($heap->{restart_client_handler});
  57.        delete $heap->{restart_client_handler};
  58.    } else {
  59.        $heap->{restart_client_handler} = $sender || 1;
  60.        stop_module($kernel);
  61.        $heap->{check_result} = 'restart';
  62.    }
  63. }


  64. sub stop_module {
  65.    my $kernel = $_[0];
  66.    for my $s (keys %Sessions) {
  67.        $kernel->signal($s, 'TERM');
  68.    }

  69. }



  70. sub go_daemon {
  71.    my $child = fork;
  72.    die "Can't fork: $!" unless defined($child);
  73.    exit(0) if $child;
  74.    POSIX::setsid();
  75.    open(STDIN,  "</dev/null");
  76.    open(STDOUT, ">/dev/null");
  77.    open(STDERR, '>&STDOUT');
  78.    umask(0);
  79. }


  80. sub client_input {
  81.     my ( $heap, $input ) = @_[ HEAP, ARG0 ];
  82.     $heap->{client}->put($input);
  83.     if ($input eq "quit"){
  84.    $_[KERNEL]->yield("shutdown");
  85.     return;
  86.     }
  87. }

复制代码

论坛徽章:
0
66 [报告]
发表于 2011-03-04 15:24 |只看该作者

  1. 第1题
  2. !!x
复制代码

论坛徽章:
0
67 [报告]
发表于 2011-03-08 10:04 |只看该作者
perl 第五版白看了,一体都答不上来。

论坛徽章:
0
68 [报告]
发表于 2011-03-08 14:59 |只看该作者
1

1. 请正确的精简如下代码。

sub myfunc {
    $x?$x:'';
}

论坛徽章:
0
69 [报告]
发表于 2011-03-08 15:01 |只看该作者
2.
undef

论坛徽章:
0
70 [报告]
发表于 2011-03-08 15:03 |只看该作者
2.
undef
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP