我正在尝试在Java8的Stream API的帮助下验证一个IMEI编号。
private void ValidateIMEI() {
field //a field holding an IMEI Number
.getText().chars()
.map(this::ConvertASCIIToNumer);
}我被卡住的部分是将偶数加倍并除以10。
最初,我尝试了传统的for循环:
private void ValidateIMEI() {
int[] numbers = field //a field holding an IMEI Number
.getText().chars()
.map(this::ConvertASCIIToNumer).toArray();
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
//Double the even number and divide it by 10. add quotient and remainder
if ((numbers[i]+1) % 2 == 0) {
numbers[i] = numbers[i] * 2;
numbers[i] = numbers[i] / 10 + numbers[i] % 10;
}
sum += numbers[i];
}
if (sum%10==0) {
status.setText("Valid");
}
else{
status.setText("InValid");
}
}但是代码坏了,尤其是使用了For循环,这是我不想要的。
那么,有谁可以在Java8中只使用Stream API来帮助实现Luhn algorithm呢?
ConvertASCIIToNumer代码:
private int ConvertASCIIToNumer(int value) {
return Character.digit(value, 10);
}发布于 2015-11-08 17:00:14
您的错误是,当您应该将具有偶数索引的数字加倍时,您却将偶数加倍。由于索引在此算法中很重要,因此我建议使用索引的IntStream:
boolean isValid =
IntStream.range(0,numbers.length)
.map (i -> (((i%2) ^ (numbers.length%2)) == 0) ? ((2*numbers[i])/10+(2*numbers[i])%10) : numbers[i])
.sum() % 10 == 0;编辑:我刚刚更改了条件,因为数组的长度决定了奇数索引还是偶数索引应该乘以2。
如果数组的长度为偶数,则偶数索引中的数字应加倍:
Index 0 1 2 3 4 5
Digit 1 5 2 5 2 6
- - -如果数组的长度是奇数,奇数索引中的数字应该是双精度的:
Index 0 1 2 3 4
Digit 1 5 2 5 2
- -发布于 2015-11-09 07:51:46
这是我能做的最漂亮的东西了:
String num; // your IMEI number
int[] a = {num.length() % 2 == 0 ? 1 : 2}; // 1 if length even, 2 otherwise
boolean isLuhn = num.chars()
.map(i -> i - '0') // convert to the int equivalent
.map(n -> n * (a[0] = a[0] == 1 ? 2 : 1)) // multiply by 1, 2 alternating
.map(n -> n > 9 ? n - 9 : n) // handle sum of digits
.sum() % 10 == 0; // mod 10 should be zero这里使用的一个“技巧”是使用int[]而不是int变量来保存乘数。这是一个变通办法,只允许引用“有效的最终”变量;数组引用实际上是最终的,但它的内容(只有一个元素)不是必须的!
https://stackoverflow.com/questions/33592167
复制相似问题