如何实现Luhn算法?
问题内容:
我正在尝试创建一个程序来验证基于luhn算法的10到12位数字长序列,但是我的程序不断告诉我,每个数字都是无效的,即使不是无效的。
这个数字应该是有效的,但是我的代码却不这样认为: 8112189876
该编号无效,我的程序同意此编号,因为它认为每个编号都无效: 8112189875
这是我的代码:
static void luhn(){
System.out.print("Enter number to validate:\n");
String pnr = input.nextLine();
int length = pnr.length();
int sum = 0;
for (int i = 1, pos = length - 1; i < 10; i++, pos--){
char tmp = pnr.charAt(pos);
int num = tmp - 0
int product;
if (i % 2 != 0){
product = num * 1;
}
else{
product = num * 2;
}
if (product > 9)
product -= 9;
sum+= product;
boolean valid = (sum % 10 == 0);
if (valid){
System.out.print("Valid!\r");
}
else{
System.out.print("Invalid!");
}
}
}
问题答案:
我看到的第一件事是您拥有:
int num = tmp - 0
您应该改为:
int num = tmp - '0';
其次,您应该在循环 外 验证和for
,因为您只关心处理完所有数字后的和。
第三,您从数字的末尾开始,并且不包括字符串的第一个数字。为什么不同时使用i
这两个任务?
结果(工作)方法:
static void luhn(){
System.out.print("Enter number to validate:\n");
String pnr = input.nextLine();
// this only works if you are certain all input will be at least 10 characters
int extraChars = pnr.length() - 10;
if (extraChars < 0) {
throw new IllegalArgumentException("Number length must be at least 10 characters!");
}
pnr = pnr.substring(extraChars, 10 + extraChars);
int sum = 0;
// #3: removed pos
for (int i = 0; i < pnr.length(); i++){
char tmp = pnr.charAt(i);
// #1: fixed the '0' problem
int num = tmp - '0';
int product;
if (i % 2 != 0){
product = num * 1;
}
else{
product = num * 2;
}
if (product > 9)
product -= 9;
sum+= product;
}
// #2: moved check outside for loop
boolean valid = (sum % 10 == 0);
if (valid){
System.out.print("Valid!\r");
}
else{
System.out.print("Invalid!");
}
}
从风格上讲 ,如果代替方法签名,则此方法会更有用
static void luhn() {
相反,它具有方法签名
static boolean luhn(String input) {
这很容易让您的代码String
从任何来源(文件,硬编码等)获取,并对结果做任何事情(像打印消息一样打印消息,或执行其他操作)。很明显,你会移动System.out.print
,input.nextLine()
以及if(valid)
这种方法的代码之外的位。
完整的重构程序:
import java.util.Scanner;
public class Luhn {
private static Scanner input;
public static void main(String... args) {
input = new Scanner(System.in);
System.out.print("Enter number to validate:\n");
String pnr = input.nextLine();
boolean result = luhn(pnr);
printMessage(result);
input.close();
}
static boolean luhn(String pnr){
// this only works if you are certain all input will be at least 10 characters
int extraChars = pnr.length() - 10;
if (extraChars < 0) {
throw new IllegalArgumentException("Number length must be at least 10 characters!");
}
pnr = pnr.substring(extraChars, 10 + extraChars);
int sum = 0;
for (int i = 0; i < pnr.length(); i++){
char tmp = pnr.charAt(i);
int num = tmp - '0';
int product;
if (i % 2 != 0){
product = num * 1;
}
else{
product = num * 2;
}
if (product > 9)
product -= 9;
sum+= product;
}
return (sum % 10 == 0);
}
private static void printMessage(boolean valid) {
if (valid){
System.out.print("Valid!\r");
}
else{
System.out.print("Invalid!");
}
}
}