栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CS50X 习题集 problem set 1,week 1,Credit.c

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CS50X 习题集 problem set 1,week 1,Credit.c

第一次写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 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021862.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号