Perl 打印100万到1000万之间的阿姆斯特朗数字

Perl 打印100万到1000万之间的阿姆斯特朗数字,perl,Perl,如何使用for循环或while循环打印来编写逻辑 有人好心地解释如何打印介于1到1,00,00000之间的阿姆斯特朗数字 这就是我遵循的算法 step 1 : initializing variable min,max,n,sum,r,t step 2 : my $n = <>; step 3 : to find base of $n step 4 : using for loop ( for (n = min; n < max ; n++ ) step 5

如何使用
for
循环或
while
循环打印来编写逻辑

有人好心地解释如何打印介于1到1,00,00000之间的阿姆斯特朗数字

这就是我遵循的算法

step 1 : initializing variable min,max,n,sum,r,t
step 2 : my $n = <>;
step 3 : to find base of $n
step 4 : using for loop 
        ( for (n = min; n < max ; n++ )
step 5 : some logic like 
        n=t,sum =0,r=t%10,t=n/10,
step 6 : 
        sum = sum + (n ^ base );
step 6 : 
        if ( sum == num ) print Armstrong numbers else not.
步骤1:初始化变量min、max、n、sum、r、t
步骤2:我的$n=;
步骤3:找到$n的基数
步骤4:使用for循环
(对于(n=min;n
我试着编写代码我的代码是这样的

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $n;
chomp($n);

my $min = 1;
my $max = 10000000
my $r;
my $sum;
my $t;

my $base = length($n);
print "base is $base\n";

for ($n = $min; $n <= $max; $n++) {
  $t = $n;
  $sum = 0;
  while ($t != 0) {
    $r = $t % 10;
    $t = $t / 10;
    {
      $sum = $sum + ($base * $r);
    }
    if ($sum == $n) {
      print "$n\n";
    }
  }
}
!/usr/bin/perl
严格使用;
使用警告;
使用诊断;
我的$n;
咀嚼(n美元);
我的$min=1;
我的$max=10000000
我的$r;
我的$sum;
我的$t;
我的$base=长度($n);
打印“基数为$base\n”;
为了($n=$min;$n在大学里做了这个。。。
我找到了我用C编写的一个,并为您将其转换为perl(这可能不是最好的方法,但我就是这样做的):

!/usr/bin/env perl
严格使用;
使用警告;
我的$min=1;
我的$max=10000000;

对于(my$number=$min;$number您的代码似乎是正确的,但是您在开始时遇到了一些问题。例如,您没有从
STDIN
@ARGV
读取数据。您会这样做吗?您只是在计算指数计算时遇到了一个小问题。在大多数编程语言中,指数的语法是ial计算是
**
pow()函数。
我真的不明白这部分是什么:

while ($t != 0) {
    $r = $t % 10;
    $t = $t / 10;
    {
      $sum = $sum + ($base * $r);
    }
    if ($sum == $n) {
      print "$n\n";
    }
}
什么是裸块?为什么要使用模数?我给你一个小代码,用于计算阿姆斯特朗数,基数为
1..100
,介于0和1000万之间:

#!/usr/bin/perl
use strict;
use warnings;
foreach my $base (0..100) {               # use the foreach loop as base
  for my $num (0..10_000_000) {           # and use numbers between this range
    my $ce=0;                             # ce = calculated exp.
    foreach my $num2 (split //,$num ) {   # split each number for calc each
      $ce += $num2 ** $base;              # exp. and adding it (see algorithm)
    }
    if ($num == $ce) {                    # when the exp. num and the number
      print "$base => $num\n";            # itself equals, its a armstrong number
    }                                     # print that
  }
}
有几件事:

  • 在需要之前用
    my
    声明某个东西是不好的做法
  • 您必须记住,数字也是字符串,可以由字符串函数(如
    split
    )进行操作
  • 类C循环在Perl中不受欢迎,因为它们很难读取
  • 常数应该是……嗯……常数
这是我的尝试。我使用
split
将我的数字分割成一个数字数组。这比不断除以10容易得多。我只需取
@digits
数组的标量值就可以得到位数

然后我可以循环使用
@数字
,将每个数字取到
$power
的幂,并将其添加到
sum
中。我使用
map
命令进行此循环,但我也可以使用另一个
进行
循环

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);

use constant {
    MIN             => 1,
    MAX             => 1_000_000,
};

for my $number ( (+MIN..+MAX) ) {
    my @digits = split //, $number;
    my $power = @digits;
    my $sum = 0;
    map { $sum += $_**$power } @digits;
    if ( $sum == $number ) {
        say "$number is an Armstrong number";
    }
}
以及我的输出:

1 is an Armstrong number
2 is an Armstrong number
3 is an Armstrong number
4 is an Armstrong number
5 is an Armstrong number
6 is an Armstrong number
7 is an Armstrong number
8 is an Armstrong number
9 is an Armstrong number
153 is an Armstrong number
370 is an Armstrong number
371 is an Armstrong number
407 is an Armstrong number
1634 is an Armstrong number
8208 is an Armstrong number
9474 is an Armstrong number
54748 is an Armstrong number
92727 is an Armstrong number
93084 is an Armstrong number
548834 is an Armstrong number
跑起来花了五秒钟多一点的时间

我本可以做这个循环,而不是
map

for my $digit ( @digits ) {
    $sum = $sum + ( $digit ** $power);
}

你自己试一下怎么样?我试着编写我的代码,我的代码是这样的:我的$n;chomp($n);我的$min=1;我的$max=10000000我的$r;我的$sum;我的$t;我的$base=length($n);打印“base是$base\n”;用于($n=$min;$n我正在做一些我无法得到的blender,但你应该把你的代码放在你的问题中,而不是放在评论中。使用编辑按钮。此外,你应该解释你正在寻找的算法,或者链接到它。你的代码中有一个小错误:
$sum=$sum+($base*$r);
应该是
$sum=$sum+($base**$r);
(当您正确编写步骤6时)@helboy002我修改了它并修正了警告,做了一个derp时刻,在
undef
而不是
'
上拆分。可以不使用数组和foreach吗?@helboy002为什么要对自己施加这样的限制?这是家庭作业吗?@helboy002-Well可以使用
for
而不是像我的或原版C,但使用
foreach
更简洁。至于不使用数组,我相信你可以,但我不知道怎么做。我仍在大量学习perl。@LightningDust
for
foreach
在perl中完全相同:它们实际上是彼此的别名。区别在于语法。有点类似撇开它不谈,但“在你需要之前用我的电脑申报东西是不好的做法。”--我错过了这条规则。我有一个几十年的习惯,就是在程序顶部声明变量。为什么这样不好?这与perl是一种解释语言有关吗?在早期的语言中,如Fortran和Pascal,迫使您在程序开始时留出时间声明变量,这导致了这种做法。在perl中,
my
变量在词汇范围内。它们在需要时快速存在,在不再需要时快速消失。想象一个变量只在
while
循环中使用。每次通过循环时,我都会得到一个新变量,该变量与之前的变量无关。当我离开循环时,该变量不再存在。这意味着我不能意外地使用一个无意义的变量。
for my $digit ( @digits ) {
    $sum = $sum + ( $digit ** $power);
}