【问题标题】:Can someone explain why my luhn's algo fails?有人可以解释为什么我的 luhn 算法失败了吗?
【发布时间】:2020-09-29 16:48:42
【问题描述】:
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <cs50.h>

short unsigned int numlen(unsigned long long n);
bool isValidCC(unsigned long long int n);
unsigned short int first_n_nums(unsigned short int n, unsigned short int x);


int main(void) 
{
    unsigned long long num = 0;
    num = get_long("Enter your card number ");
    
    if(numlen(num) == 15 && (first_n_nums(num, 2) == 34 || first_n_nums(num, 2) == 37) && isValidCC(num) == true)
    {
        printf("AMEX\n");
    }
    else if((numlen(num) == 13 || numlen(num) == 16)  && first_n_nums(num, 1) == 4 && isValidCC(num) == true)
    {
        printf("VISA\n");
    }
    else if(numlen(num) == 16 && (first_n_nums(num, 2) == 51 || first_n_nums(num, 2) == 52 || first_n_nums(num, 2) == 53 || first_n_nums(num, 2) == 54 || first_n_nums(num, 2) == 55)  && isValidCC(num) == true)
    {
        printf("MASTERCARD\n");
    }
    else
    {
        printf("INVALID\n");
    }

    
}

unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
{
    while(n > pow(10,x))
    {
        n /= 10;
    }
    return n;
}    
    
   

short unsigned int numlen(unsigned long long n)
{
    short unsigned int count = 0;
    while (n !=0)
    {
        n /= 10;  //removes last digit
        count++; //counts the num of digits removed
    }
    return count;
}

bool isValidCC(unsigned long long int n)
{

    // take user input and add elements to array in reverse
     int arr1[(numlen(n))]; // declares but can't Initialize an array of n ;
     
     for (int i = 0; i < (int)sizeof(arr1)/sizeof(int) ; i++)
    {
        arr1[i] = 0;
    }
    
    for (int i = 0 ; i <(int) (sizeof(arr1)/sizeof(int)) ; i++)
    {
        arr1[i] = n % 10; //Appends last digit to an array
        n /= 10; // removes that last digit
    }
    
    
    // since arr1 = x digits long, arr2 is every second digit so its x/2 long 
     int arr2[((sizeof(arr1)/sizeof(int))*2)];
    
    //initializing garbage data to 0
    for (int i = 0; i < sizeof(arr2)/sizeof(int) ; i++)
    {
        arr2[i] = 0;
    }
    
    // multiplies, seperates, and sums arr2 elements
    int sum_of_arr2 = 0;
    for (int i = 1,  a = 0,  b = 0 ; i < (sizeof(arr1)/sizeof(int)) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
    {
        a = arr1[i] * 2;
        if( a > 9)
        {
            b = a % 10;
            a /= 10;
            arr2[i] = b;
            sum_of_arr2 += b;
        }
        arr2[i-1] = a; // cz i currenrly is one idex ahead
        sum_of_arr2 += a;
    }
    
    // adds other elements of arr1 to sum_of_arr2
    for (int i = 0 ; i < (sizeof(arr1)/4) ; i += 2) // sizeof(array) = n of elements * sizeof(type of n)
    {
        sum_of_arr2 += arr1[i];
    }
    
    // returns true or false
    if (sum_of_arr2 % 10 != 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}

有人可以解释一下为什么这对于以下值会失败:

371449635398431 - 应为“AMEX\n”,而不是“INVALID\n”

5555555555554444 - 应为“MASTERCARD\n”,而不是“INVALID\n”

5105105105105100- 预期为“MASTERCARD\n”,而不是“VISA\n”

4111111111111111 - 预期为“VISA\n”,而不是“INVALID\n”

4222222222222 - 预期为“VISA\n”,而不是“INVALID\n”

【问题讨论】:

  • 我们需要看看first_n_numsisValidCCnumlen 有什么帮助。此代码原样不会编译,因此我们甚至无法做出正确的猜测。我会打开一个调试器并查看每个函数返回的内容,以使每个函数都按照您的预期进行......
  • while(n &gt; pow(10,x)) 移至基于整数的解决方案,而不是导致 FP 不准确。
  • 您不应该为此使用浮点数。事实上,您可能不应该使用整数。字符串将提供更通用的表示,不受长度限制。
  • 你可以只是return (sum_of_arr2 % 10 == 0); 同样你的数组归零是没有用的,因为你无论如何都要填写每个数字......
  • 今天是学习使用调试器的好日子。每天都是学习使用调试器的好时机。这也是学习单元测试概念的好日子。你的first_n_nums 做你想做的事吗?

标签: c if-statement cs50


【解决方案1】:

你的问题出在你的功能上

    unsigned short int first_n_nums(unsigned short int n, unsigned short int x)

您传递的是unsigned short int 而不是unsigned long long,因此您只能获得unsigned short int 的最大值而不是实际值。

输出:

    371449635398431 - "AMEX\n"

    5555555555554444 - "MASTERCARD\n"

    5105105105105100- "MASTERCARD\n"

    4111111111111111 - "INVALID\n" - Note that the output you said you were expecting is incorrect because the input length is 14 instead of 13.

    4222222222222 - "VISA\n"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    相关资源
    最近更新 更多