Java 将长整型转换为单独的数字,并反向填充为向量
首先,这是一个关于信用卡号码验证的学校项目。 基本上,我正在尝试将CC数的长整数转换为向量,以便可以根据需要操纵每个数字。我是用%10的方法来做的。由于这将使我的向量的数字从右到左向后,因此我将从ccNum.size-1开始以增量设置向量,并向后操作,以便向量中的值与用户输入的顺序相同。 问题是,处理的第一个值使最后9位左右的输入被错误地放入向量中。我试着重新构造循环,复制到一个数组中,然后将其反转到向量中,还有其他我的大脑无法跟踪的事情。我尽可能地对我的代码进行注释,以概述正在发生的事情,如下所示:Java 将长整型转换为单独的数字,并反向填充为向量,java,Java,首先,这是一个关于信用卡号码验证的学校项目。 基本上,我正在尝试将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;
}
}
如您所见,数字的前半部分正确显示,后半部分循环显示。如果有人有一个解决方案那就太棒了
为其他可能陷入困境的人提供参考-这就是我最后做的,看起来也更干净,谢谢大家的帮助
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;
}
}
}
我建议您像我的清单中一样使用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;
}
试着替换
(int) ccNumber % 10
借
如果您先强制转换为int,然后执行模10,则当int值溢出时,它将不起作用。我建议您不要使用Vector-这是一种不推荐使用的集合类型-改用列表。甚至一个数组。在任何情况下,您都可以使用Collections.reverse在填充列表后将其反转。。。另一件需要注意的事情是,增强型for循环比手动迭代可读性强得多……这是一个学校项目,难道你不能将卡号解析为字符串,并将其按相反顺序拆分为数字吗?我肯定会研究增强型for循环,我以前从未听说过它们。我会尝试重新做一个清单项目,并清理一些东西了。目前,尼古拉斯的回答实际上解决了这个问题。它不需要向量,我在上学期用C++学习了它们,并且认为在爪哇也没问题。我还试图避免使用字符串,我认为它可能会更复杂,因为我以后需要这些值。谢谢你的帮助!谢谢,我不敢相信它这么简单,就像一个符咒,我会投赞成票,但我没有这个-Integer.parseIntString.valueOfcardNumber.charAti的名声太可怕了。真正地你怎么了??但它是有效的。。。只要它工作正常,就没有关于如何编写它的争论。ifmyValue==Boolean.True!=Boolean.False==true也适用于测试条件。它仍然会被否决。哦。。。无可奉告。我的表达式不是布尔求值,因此与上面的示例相比,阅读起来就不那么复杂了。
(int) ccNumber % 10
(int) (ccNumber % 10)