使用 Java 8 条流检查给定号码是否为 Armstrong 号码

Checking if the Given numger is an Armstrong number with Java 8 Streams

我在检查提供的号码是否为 Armstrong 时遇到问题。

我正在传递 370int 值,但结果我得到了 343 的值。

有人可以指出我遗漏了什么吗?

输入: 370 预期: 370

static int isArmStrong(int num) {
    return IntStream.rangeClosed(1, num)
            .map(i -> i / 10)
            .map(i -> i % 10)
            .reduce(1, (a, b)-> (b * b * b));       
}

您必须遍历给定数字的数字。但相反,您创建了从 1 到给定数字(含)的数字流。

并且您 hard-coded 3 是(即您的解决方案仅用于处理 3 位数字)。

此外,reduce 操作中存在错误:

reduce(1,(a,b)-> (b*b*b))

您的方法实际上是 returns 是流中最后一个元素的立方体,对于输入 370 恰好是 7。因为您忽略了累加器中的参数 aa - 表示到目前为止累计的总和,b - 是下一个元素)。

如果 isArmstrong 方法会 return 一个 boolean 值会更好。因为它意味着按照您的方式执行检查,并且按照惯例,以 ishas 开头的方法预计会 return a boolean.

要正确解决此问题,您需要遵循经典算法 (wiki) 迭代给定数字的数字。

您可以通过 iterate() 操作对流进行处理。它的 Java 8 有两个参数(a seedunary operator 用于生成下一个元素) 创建一个无限流。您需要将 limit() 操作应用于 trim 流中的 个元素数 个数字 中给定的数字。

应用map()得到每个元素的次幂然后应用终端操作sum()得到结果

public static boolean isArmstrong(int num) {
    return num == getArmstrongSum(num);
}

public static int getArmstrongSum(int num) {
    int pow = String.valueOf(num).length();
    return IntStream.iterate(num, i -> i / 10)
            .limit(pow)
            .map(i -> (int) Math.pow(i % 10, pow))
            .sum();
}

main()

public static void main(String[] args) {
    System.out.println(getArmstrongSum(370));
    System.out.println(isArmstrong(370));
}

输出

370
true

用 java 8 流生成 Armstrong 编号列表。

static boolean isArmStrong(int num) {
    return num==armStrongViaStream(num);
}

//via Stream
static int armStrongViaStream(int num) {
    int size = String.valueOf(num).length();
    return IntStream.iterate(num, i->i/10)
            .limit(size)
            .map(i-> (int)Math.pow(i%10, size))
            .sum();
        }

//List via Stream
static List<Integer> armStrongListUpto(int num){
    List<Integer> list=new ArrayList<>();
    list=IntStream.rangeClosed(0, num)
            .filter(i->isArmStrong(i)).boxed()
            .collect(Collectors.toList());
return list;    
}

主要方法

System.out.println("List via Java Stream ->"+armStrongListUpto(500));

输出将return一个列表。

List via Java Stream ->[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407]

如果我们需要在 Java 8 个流中的范围内生成阿姆斯壮编号列表。

static List<Integer> armStrongBetweenNum(int start,int end){
    List<Integer> list=new ArrayList<>();
    list=IntStream.rangeClosed(start, end)
            .filter(i->isArmStrong(i)).boxed()
            .collect(Collectors.toList());
    return list;
}

主要功能(调用)

System.out.println("Armstrong num between given end points ->"+armStrongBetweenNum(1, 500));

输出

Armstrong num between given end points ->[1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407]