使用 Java 8 条流检查给定号码是否为 Armstrong 号码
Checking if the Given numger is an Armstrong number with Java 8 Streams
我在检查提供的号码是否为 Armstrong 时遇到问题。
我正在传递 370
的 int
值,但结果我得到了 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
。因为您忽略了累加器中的参数 a
(a
- 表示到目前为止累计的总和,b
- 是下一个元素)。
如果 isArmstrong
方法会 return 一个 boolean
值会更好。因为它意味着按照您的方式执行检查,并且按照惯例,以 is
或 has
开头的方法预计会 return a boolean
.
要正确解决此问题,您需要遵循经典算法 (wiki) 迭代给定数字的数字。
您可以通过 iterate()
操作对流进行处理。它的 Java 8 有两个参数(a seed 和 unary 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]
我在检查提供的号码是否为 Armstrong 时遇到问题。
我正在传递 370
的 int
值,但结果我得到了 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
。因为您忽略了累加器中的参数 a
(a
- 表示到目前为止累计的总和,b
- 是下一个元素)。
如果 isArmstrong
方法会 return 一个 boolean
值会更好。因为它意味着按照您的方式执行检查,并且按照惯例,以 is
或 has
开头的方法预计会 return a boolean
.
要正确解决此问题,您需要遵循经典算法 (wiki) 迭代给定数字的数字。
您可以通过 iterate()
操作对流进行处理。它的 Java 8 有两个参数(a seed 和 unary 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]