如何计算C中无符号长数的奇数位数

时间:2018-01-27 09:04:10

标签: c

我教授的规则是:

使用签名编写递归函数:

npm build

该函数获得一个自然正数int check_odd(unsigned long n); 。该函数需要检查n中出现的不同奇数的数量是否小于3.如果它们是:返回1否则返回0。 您不能使用任何其他函数,也不能使用静态/全局变量。

示例:

n

这是我到目前为止所做的代码,它起到了一定的作用:

check_odd(2169876)==0 
check_odd(956908529)==1

这个递归函数返回数字中有多少个奇数位。现在我不知道如何继续检查数字是相同还是不同的数字,如果有3个或更多不同的奇数,我需要返回0;否则1。

3 个答案:

答案 0 :(得分:2)

@Daniel Beck Bachar:您想要将数字3比3对待是和蔼可亲的。它激励我找到解决方案。 另请注意,(n& 1)与n%2相同。

#include <stdio.h>

int check_odd(unsigned long n)
{
    int d1, d2, d3, n2;

    if (n < 100)
        return 1;

    d1 = n%10; // digit for units
    d2 = (n/10)%10; // digit for tens
    d3 = (n/100)%10; // digit for hundreds

    // We try to remove some of the three digits
    // A digit can be removed if it is even
    // Or if it is the same as another of the 2 other digit
    n2 = n / 1000;
    if ((d3&1) == 1)
        n2 = n2*10 + d3;
    if ((d2&1) == 1 && d2 != d3)
        n2 = n2*10 + d2;
    if ((d1&1) == 1 && d1 != d2 && d1 != d3)
        n2 = n2*10 + d1;
    if (n == n2) // If all 3 digits are kept, that means they are all odd and differents
        return 0;

    return check_odd(n2); // Since n2 < n, one day or the other the recursion will end.
}

int main(int argc, char **argv)
{
    unsigned int n;

    n = atoi(argv[1]);
    printf("check_odd(%d) = %d\n", n, check_odd(n));
    return 0;
}

编辑:由于运算符优先级,我将括号括在(n&1)左右,因为==首先计算。谢谢chqrlie。

答案 1 :(得分:0)

int check_odd(unsigned int n) {
  unsigned int m = 0;
  for ( ; n ; n /= 10)
    m |= (n & 1) << ((n % 10) / 2);
  m = m - ((m >> 1) & 0x55555555);
  m = (m & 0x33333333) + ((m >> 2) & 0x33333333);
  return (((m + (m >> 4) & 0xF0F0F0F) * 0x1010101) >> 24) < 3;
}

答案 2 :(得分:0)

好的,我终于解决了这个问题!

int check_odd(unsigned long n) {
    if ((n / 1000) == 0) {
        if (((n%10) != ((n%100)/10)) &&
            (n%10) != ((n%1000)/100) &&
            ((n%100)/10) != ((n%1000)/100) &&
            (n%10)%2 != 0 && ((n%100)/10)%2 != 0 && ((n%1000)/100)%2 != 0) {
            return 0;
        } else
            return 1;
    } else {
        if ((n%10)%2 == 0) {
            return check_odd(n/10);
        } else {
            int i = 100;
            while ((n%10)%2) {
                if (((n%i)/(i/10))%2 == 0) {
                    unsigned long temp = n/i;
                    n = (temp*(i/10)) + (n%(i/10));
                    return check_odd(n);
                } else
                if (((n%10)) == ((n%i)/(i/10))){
                    return check_odd(n/10);
                }
                i = i * 10;
            }
        }
    }
    return 0;
}