第一次写csdn。。。记录2022.07.21 01:27
题目要求信用卡总共三种,VISA,Mastercard ,American Express。其中visa是13位或16位数字并以4开头。Mastercard 16位数字并且是以51,52,53,54或55开头(其他的少数情况不考虑)American Express 是15位数字并且以34,37开头。
所有信用卡必须保证上述前提。并且信用卡号码中间存在一种校验和。即从倒数第二位开始,每隔一位数字都要乘以2。 比如号码: 4003600000000014 画横线的数字要乘以2。
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
得到: 2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
然后将这些数字相加,切记:十位数字要拆开相加,比如12要拆成1和2进行相加。
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
然后加上那些没有乘以2 的数字,即 4003600000000014 中未划横线的数字。
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
相加结果为20,这就是校验和。然后检查校验和,个位数字满不满足等于0。如果为0,则为合法卡,不为0,则为非法卡。
最后结合卡的类型进行输出。比如 4003600000000014 输出为 VISA。
目录
以下为解题步骤
源代码(c++版本);
源代码(CS50X提交版本/c语言版)
以下为解题步骤
第一步,获取数字有多少位。我使用了如下算法。
int judge(long long int id){
int count = 0;
while(id != 0){
id = id/10;
count ++;
}
return count;
}
第二步,获得各个位次的数字,将其保存在数组当中
for(int i = count - 1 ; i >= 0 ;i-- ){
num[i] = id%10;
id = id/10;
}
第三步,按要求将数字乘以2,超过10的再创建一个数组,保存个位和十位
//设置次数组。如果一个数字位*2 >=10 ,将个位和十位拆分开分别保存起来。
int secNum[20];
//将倒数第二位开始的每个一个位次的数*2,并且将结果大于10的数拆开保存到secNum数组中。
//最后不要忘记将num[i]设置成0,防止参与后续相加。
int n = 0;
for(int i = count - 2;i >=0;i = i-2){
num[i] = num[i] * 2;
if(num[i] >= 10){
secNum[n] = num[i] % 10;
secNum[n+1] = num[i] / 10;
n = n+2;
secNum[n] = 0;
num[i] = 0;
}
第四步,求和
//求和
int sum = 0;
for(int i = 0; i
第五步,判断卡的型号。
//保存前两个数字位,用于判断卡的型号
int firstNum[2];
firstNum[0] = num[0];
firstNum[1] = num[1];
//判断卡的型号
string type;
if((count == 13 ||count ==16) && firstNum[0] == 4){
type = "VISA";
}
else if(count ==16 && firstNum[0] == 5 && (firstNum[1] ==1 || firstNum[1] == 2 ||firstNum[1] ==3 || firstNum[1] == 4 || firstNum[1] == 5))
{
type = "MASTERCARD";
}
else if(count == 15 && firstNum[0] == 3 && (firstNum[1] == 4 || firstNum[1] ==7)){
type = "AMEX";
}
else{
cout<<"INVALID";
}
第五步,输出
//判断个位数字是否为0,如果为0则为合法账号,不为0则为非法账号。为0则输出最后结果
if(sum % 10 != 0){
cout<<"INVALIDn";
system("pause");
return 1;
}
else{
cout<
源代码(c++版本);
#include
#include
using namespace std;
int judge(long long int id);
int main( void ){
long long int id;
cout<<"Please enter your credit card id: ";
cin>>id;
int count = judge(id);
//判断数字位数,如果不是13、15、16 则为非法账号
if(count !=13 && count != 15 && count != 16){
cout<<"INVAILDn";
system("pause");
return 1;
}
//创建一个数组,用于保存各个数字位。因为最大为16位,所以设置成最大值。
int num[16];
//保存各个数字位
for(int i = count - 1 ; i >= 0 ;i-- ){
num[i] = id%10;
id = id/10;
}
//保存前两个数字位,用于判断卡的型号
int firstNum[2];
firstNum[0] = num[0];
firstNum[1] = num[1];
//判断卡的型号
string type;
if((count == 13 ||count ==16) && firstNum[0] == 4){
type = "VISA";
}
else if(count ==16 && firstNum[0] == 5 && (firstNum[1] ==1 || firstNum[1] == 2 ||firstNum[1] ==3 || firstNum[1] == 4 || firstNum[1] == 5))
{
type = "Mastercard";
}
else if(count == 15 && firstNum[0] == 3 && (firstNum[1] == 4 || firstNum[1] ==7)){
type = "America Express";
}
else{
cout<<"INVALID";
}
//将未使用的空间设置为0。防止随机数参与最后的相加
for(int i = count;i<16;i++){
num[i] = 0;
}
//设置次数组。如果一个数字位*2 >=10 ,将个位和十位拆分开分别保存起来。
int secNum[20];
//将倒数第二位开始的每个一个位次的数*2,并且将结果大于10的数拆开保存到secNum数组中。最后不要忘记将num[i]设置成0,防止参与后续相加。
int n = 0;
// if( count % 2 == 0){
for(int i = count - 2;i >=0;i = i-2){
num[i] = num[i] * 2;
if(num[i] >= 10){
secNum[n] = num[i] % 10;
secNum[n+1] = num[i] / 10;
n = n+2;
secNum[n] = 0;
num[i] = 0;
}
}
//求和
int sum = 0;
for(int i = 0; i
源代码(CS50X提交版本/c语言版)
#include
#include
#include
int judge(long id);
int main( void ){
long id = get_long("Number: ");
int count = judge(id);
//判断数字位数,如果不是13、15、16 则为非法账号
if(count !=13 && count != 15 && count != 16){
printf("INVALIDn");
return 0;
}
//创建一个数组,用于保存各个数字位。因为最大为16位,所以设置成最大值。
int num[16];
//保存各个数字位
for(int i = count - 1 ; i >= 0 ;i-- ){
num[i] = id%10;
id = id/10;
}
//保存前两个数字位,用于判断卡的型号
int firstNum[2];
firstNum[0] = num[0];
firstNum[1] = num[1];
//判断卡的型号
string type;
if((count == 13 ||count ==16) && firstNum[0] == 4){
type = "VISA";
}
else if(count ==16 && firstNum[0] == 5 && (firstNum[1] ==1 || firstNum[1] == 2 ||firstNum[1] ==3 || firstNum[1] == 4 || firstNum[1] == 5))
{
type = "MASTERCARD";
}
else if(count == 15 && firstNum[0] == 3 && (firstNum[1] == 4 || firstNum[1] ==7)){
type = "AMEX";
}
else{
printf("INVALIDn");
return 0;
}
//将未使用的空间设置为0。防止随机数参与最后的相加
for(int i = count;i<16;i++){
num[i] = 0;
}
//设置次数组。如果一个数字位*2 >=10 ,将个位和十位拆分开分别保存起来。
int secNum[20];
//将倒数第二位开始的每个一个位次的数*2,并且将结果大于10的数拆开保存到secNum数组中。最后不要忘记将num[i]设置成0,防止参与后续相加。
int n = 0;
for(int i = count - 2;i >=0;i = i-2){
num[i] = num[i] * 2;
if(num[i] >= 10){
secNum[n] = num[i] % 10;
secNum[n+1] = num[i] / 10;
n = n+2;
secNum[n] = 0;
num[i] = 0;
}
}
//求和
int sum = 0;
for(int i = 0; i



