将long int转换为单独的数字并反向填充到向量中

时间:2014-03-02 21:58:40

标签: java

首先,这是一个关于信用卡号验证的学校项目。 基本上我试图将long int(CC编号)转换为向量,这样我就可以根据需要操作每个数字。我是通过使用%10方式来实现的。因为这将导致我的向量具有从右到左(向后)的数字,所以我从ccNum.size() - 1开始以增量设置向量并向后工作,以便向量中的值具有相同的顺序作为用户输入。 问题是处理的第一个值(所以输入的最后9位左右)被错误地放入向量中。我已经尝试重构循环,复制到数组然后将其反转到向量中,以及我脑海中无法跟踪的各种其他事情。我试图尽可能地评论我的代码,以概述正在发生的事情,这里是:

public static void main(String[] args) {

    long creditCardNumber = 0;
    Vector<Integer> ccNum = new Vector<Integer>(13,3);
    Vector<Integer> oddNum = new Vector<Integer>(6,1);
    Vector<Integer> evenNum = new Vector<Integer>(6,1);

    creditCardNumber = getInput(creditCardNumber);
    int size = getSize(creditCardNumber);

     //Pre-populate the vector so that I can add values starting from behind
     //this makes it so that the credit card number isn't backwards. I also
     //did it so that it matches the size of the input to prevent false values
             //Yes, I verified the getSize method works.
     for (int k = 0; k < size; k++) {
         ccNum.add(k);
     }

     //I made a copy of the variable so I don't screw it up in the loop
     long ccNumber = creditCardNumber;

     //THIS IS WHERE THE PROBLEM IS.
     for (int j = 0; ccNumber > 0; j++){
         //on the first iteration, set the final index of ccNum array to
         //final value of input using %10
         if (j == 0){
         ccNum.set(ccNum.size() - 1, (int) ccNumber % 10);
         ccNumber /= 10;
         //This just prints the value of ccNumber afterwards so that I can
         //keep track of whats going on and make sure everything is "working"
         System.out.println(ccNumber);
         } else {
         //Here I am continuously setting the values going backwards
         //I end up with the same amount of values as the input but some
         //are wrong
         ccNum.set(ccNum.size() - (j+1), (int) ccNumber % 10);
         ccNumber /= 10;
         System.out.println(ccNumber);
         }
     }
     //Here is where I print out all the values in the ccNum vector.
     for (int l = 0; l < size; l++) {
         System.out.print(ccNum.get(l));
     }
    System.out.println("");

    for (int i = 0; i < ccNum.size() - 1; i ++) {
        if (i % 2 == 0) {
            evenNum.add(getDigit(ccNum.get(i)));
        } else {
            oddNum.add(ccNum.get(i));
        }
    }

    int prefix = getPrefix(ccNum);
    int sumEven = sumOfDoubleEvenPlace(evenNum);
    int sumOdd = sumOfOddPlace(oddNum);

    if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
        System.out.printf("%d: is valid", creditCardNumber);
    } else {
        System.out.printf("%d: is invalid", creditCardNumber);
    }
}

private static int sumOfOddPlace(Vector<Integer> oddNum) {
    int sum = 0;
    for (int i = 0; i < oddNum.size() - 1; i++) {
        sum += oddNum.get(i);
    }
    return sum;
}

private static int sumOfDoubleEvenPlace(Vector<Integer> evenNum) {
    int sum = 0;
    for (int i = 0; i < evenNum.size() - 1; i++) {
        sum += evenNum.get(i);
    }
    return sum;
}

private static int getDigit(int x) {
    int y = x*2;

    if (y < 10) {
        return y;
    } else {
        int sum = 0;
        while (y > 0) {
            sum += y % 10;
            y /= 10;
        }
        return sum;
    }
}

private static int getPrefix(Vector<Integer> ccNum) {
    if (ccNum.get(0) == 4) {
    return 4;
    } else if (ccNum.get(0) == 5) {
        return 5;
    } else if (ccNum.get(0) == 6) {
        return 6;
    } else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
        return 37;
    } else {
        return 0;
    }
}

private static int getSize(long creditCardNumber) {

    int size = (int)(Math.log10(creditCardNumber)+1);
    return size;
}

private static long getInput(long creditCardNumber){
    Scanner input = new Scanner(System.in);
    System.out.print("Enter a credit card number: ");
    creditCardNumber = input.nextLong();
    input.close();
    return creditCardNumber;
}

private static boolean isValid(Vector<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {

    if (size < 13 || size > 16) {
        return false;
    } else if (prefixMatched(prefix) == false) {
        return false;
    } else if ((sumEven + sumOdd) % 10 != 0) {
        return false;
    } else {
    return true;
    }

}

private static boolean prefixMatched(int prefix) {
    if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
        return true;
    } else {
        return false;
    }
}

这是输出:

Enter a credit card number: 4388576018410707
438857601841070
43885760184107
4388576018410
438857601841
43885760184
4388576018
438857601
43885760
4388576
438857
43885
4388
438
43
4
0
438857601249-2-16-3
4388576018410707: is invalid

正如您所看到的,数字的前半部分是正确的(后半部分是循环的)。如果有人有一个很棒的解决方案。

对于可能会遇到困难的其他人的未来参考 - 这就是我最终做的事情,看起来更干净,感谢大家的帮助。

public class CreditCardNumberValidation {

    public static void main(String[] args) {

        long creditCardNumber = 0;
         //Using ArrayLists because it makes it easier to manipulate data later
        ArrayList<Integer> ccNum = new ArrayList<Integer>();
        ArrayList<Integer> oddNum = new ArrayList<Integer>();
        ArrayList<Integer> evenNum = new ArrayList<Integer>();
        //Getting input in different method to clean up the code
        creditCardNumber = getInput(creditCardNumber);
        int size = getSize(creditCardNumber);
         //Split creditCardNumber into separate integers and store in ArrayList
         long ccNumber = creditCardNumber;
         for (int j = 0; ccNumber > 0; j++){
             ccNum.add((int) (ccNumber % 10));
             ccNumber /= 10;
         }
         //Reverse the collection so that the numbers are in order
         Collections.reverse(ccNum);
         //Using the main List, even and odd numbers are sorted
        for (int i = 0; i < ccNum.size(); i ++) {
            if (i % 2 == 0) {
                evenNum.add(getDigit(ccNum.get(i)));
            } else {
                oddNum.add(ccNum.get(i));
            }
        }

        int prefix = getPrefix(ccNum);
        int sumEven = sumOfDoubleEvenPlace(evenNum);
        int sumOdd = sumOfOddPlace(oddNum);

        if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
            System.out.printf("%d is valid", creditCardNumber);
        } else {
            System.out.printf("%d is invalid", creditCardNumber);
        }
    }

    private static int sumOfOddPlace(ArrayList<Integer> oddNum) {
        int sum = 0;
        for (int i = 0; i < oddNum.size(); i++) {
            sum += oddNum.get(i);
        }
        return sum;
    }

    private static int sumOfDoubleEvenPlace(ArrayList<Integer> evenNum) {
        int sum = 0;
        for (int i = 0; i < evenNum.size(); i++) {
            sum += evenNum.get(i);
        }
        return sum;
    }

    private static int getDigit(int x) {
        int y = x*2;

        if (y < 10) {
            return y;
        } else {
            int sum = 0;
            while (y > 0) {
                sum += y % 10;
                y /= 10;
            }
            return sum;
        }
    }

    private static int getPrefix(ArrayList<Integer> ccNum) {
        if (ccNum.get(0) == 4) {
        return 4;
        } else if (ccNum.get(0) == 5) {
            return 5;
        } else if (ccNum.get(0) == 6) {
            return 6;
        } else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
            return 37;
        } else {
            return 0;
        }
    }

    private static int getSize(long creditCardNumber) {
        //Easy way of getting the size of an integer without modifying it
        return (int)(Math.log10(creditCardNumber)+1);
    }

    private static long getInput(long creditCardNumber){
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a credit card number: ");
        creditCardNumber = input.nextLong();
        input.close();
        return creditCardNumber;
    }

    private static boolean isValid(ArrayList<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {
        // Check size, prefix, and sum, if all tests pass return true
        if (size < 13 || size > 16) {
            return false;
        } else if (prefixMatched(prefix) == false) {
            return false;
        } else if ((sumEven + sumOdd) % 10 != 0) {
            return false;
        } else {
        return true;
        }   
    }

    private static boolean prefixMatched(int prefix) {
        if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
            return true;
        } else {
            return false;
        }
    }

}

2 个答案:

答案 0 :(得分:0)

尝试替换

(int) ccNumber % 10

通过

(int) (ccNumber % 10)

如果先转换为int然后再执行模10,那么当int值溢出时它将无效。

答案 1 :(得分:-1)

我建议你在我的列表中使用ArrayList。我的函数返回Long中的整数的简单arraylist。

public List<Integer>getCardNumbers(Long longCardNumber){
 String cardNumber = longCardNumber.toString();
 List<Integer> intCardNumberList = new ArrayList<Integer>();
    for(int i=0;i<cardNumber.length();i++){
        intCardNumberList.add(Integer.parseInt(String.valueOf(cardNumber.charAt(i))));
    }
    return intCardNumberList;
}