首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java 8 Stream实现Luhn算法

用Java 8 Stream实现Luhn算法
EN

Stack Overflow用户
提问于 2015-11-08 16:42:44
回答 2查看 1.9K关注 0票数 4

我正在尝试在Java8的Stream API的帮助下验证一个IMEI编号。

代码语言:javascript
复制
private void ValidateIMEI() {
    field //a field holding an IMEI Number
            .getText().chars()
            .map(this::ConvertASCIIToNumer);
}

我被卡住的部分是将偶数加倍并除以10。

最初,我尝试了传统的for循环:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
private int ConvertASCIIToNumer(int value) {
    return Character.digit(value, 10);
}
EN

回答 2

Stack Overflow用户

发布于 2015-11-08 17:00:14

您的错误是,当您应该将具有偶数索引的数字加倍时,您却将偶数加倍。由于索引在此算法中很重要,因此我建议使用索引的IntStream

代码语言:javascript
复制
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。

如果数组的长度为偶数,则偶数索引中的数字应加倍:

代码语言:javascript
复制
Index 0 1 2 3 4 5

Digit 1 5 2 5 2 6
      -   -   -

如果数组的长度是奇数,奇数索引中的数字应该是双精度的:

代码语言:javascript
复制
Index 0 1 2 3 4

Digit 1 5 2 5 2
        -   -
票数 2
EN

Stack Overflow用户

发布于 2015-11-09 07:51:46

这是我能做的最漂亮的东西了:

代码语言:javascript
复制
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变量来保存乘数。这是一个变通办法,只允许引用“有效的最终”变量;数组引用实际上是最终的,但它的内容(只有一个元素)不是必须的!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33592167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档