打印阿姆斯壮数字在1到1千万之间

时间:2013-08-07 10:10:30

标签: perl

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

有人解释如何打印1到1,00,000之间的阿姆斯壮数字。

这是我遵循的算法

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.

我尝试编写代码,我的代码看起来像这样

#!/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";
    }
  }
}

3 个答案:

答案 0 :(得分:1)

有几件事:

  • 在您需要之前用my声明某些内容是不好的做法。
  • 您必须记住,数字也是字符串,可以通过split等字符串函数进行操作。
  • 在Perl中不鼓励使用类似C的循环,因为它们难以阅读。
  • 常数应该是......好吧...... 常数

这是我的尝试。我使用split将我的数字拆分成一个数字数组。这比不断分成十个容易得多。我可以通过简单地获取@digits数组的标量值来获取位数。

然后,我可以循环浏览@digits,将每个$power强加给sum并将其添加到map。我在这个循环中使用for命令,但我也可以使用另一个#! /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); } ,我可以完成这个循环:

{{1}}

答案 1 :(得分:0)

这个人在大学里做过......

我挖出了我用C制作的那个并将它转换为perl(它可能是最好的方法,但这是我做的方式):

#!/usr/bin/env perl

use strict;
use warnings;

my $min = 1;
my $max = 10000000;

for (my $number = $min; $number <= $max; $number++) {
    my @digits = split('', $number);
    my $sum = 0;
    foreach my $digit (@digits) {
        $sum += $digit**length($number);
    }
    if ($sum == $number) {
        print "$number\n";
    }
}

Demo - 1 to 9999 due to execution time limit

答案 2 :(得分:0)

您的代码似乎是正确的,但您在开始时遇到了一些问题。例如,您不是从STDIN@ARGV读取的。你会这样做,你计算指数计算时遇到一个小问题。在大多数编程语言中,指数计算的语法是**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
  }
}