#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int CheckNumber(long long int x);
int prime(long long int n);
int armstrong(long long int z);
int perfect(long long int y);

int main()
{
    long long int i;
    long long int x;
    for (i = 1; i > 0; i++)
    {
        long long int n, s;
        printf("\nEnter a number to be checked:");
        scanf("%lld", &n);
        s = CheckNumber(n);
        switch (s)
        {
        case (0):
            printf("\nThis number is Prime");
            break;
        case (1):
            printf("\nThis number is Perfect");
            break;
        case (2):
            printf("\nThis number is Armstrong");
            break;
        case (3):
            printf("\nThis number is Armstrong & Prime");
            break;
        case (4):
            printf("\nThis number is Armstrong & Perfect.");
            break;
        case (5):
            printf("\nThis number is otherwise.");
            break;
        }
        printf("\n\nwant to check another number?\n(1) to continue (0) to close.");
        scanf("%lld", &x);
        if (x == 0)
        {
            break;
        };
    }
    return 0;
}

int prime(long long int n)
{
    long long i, check = 0;
    if (n == 0 || n == 1)
        check = 1;

    for (i = 2; i <= n / 2; ++i)
    {
        if (n % i == 0)
        {
            check = 1;
            break;
        }
    }
    if (check == 0)
    {
        return 0;
    }
    return 1;
}

int perfect(long long int y)
{
    long long int n, i = 1, np = 0;
    n = y;
    do
    {
        if (n % i == 0)
        {
            np = np + i;
        }
        i++;
    } while (i != n);
    if (np == n)
    {
        return 1;
    }
    return 2;
}

int armstrong(long long int z)
{
    long long int  nfi, i, host, sum = 0, y;
    y = z;
    if (z == 0)
    {
        return 2;
    }
    nfi = floor(log10(y) + 1);
    for (i = 1; i <= nfi; i++)
    {
        host = y % 10;
        sum += pow(host, nfi);
        y = y / 10;
    }
    if (z == sum)
    {
        return 2;
    }
    return 3;
}

int CheckNumber(long long int x)
{
    if (x == 0 || x == 1)
    {
        return 2;
    }
    if (prime(x) == 0)
    {
        if (armstrong(x) == 2)
        {
            return 3;
        }
        else
        {
            return 0;
        }
    }
    else if (perfect(x) == 1)
    {
        if (armstrong(x) == 2)
        {
            return 4;
        }
        else
        {
            return 1;
        }
    }
    else if (armstrong(x) == 2)
    {
        return 2;
    }
    else
    {
        return 5;
    }
}

这段代码有四个功能.

  • 函数prime用于判断一个数字是否为质数;如果是质数,则返回0,如果不是,则返回1.

  • 函数perfect用于判断数字是否完全;如果完全,则返回1,如果不完全,则返回2.

  • 函数armstrong用于判断数字是否为阿姆斯特朗;如果是阿姆斯特朗,则返回2,如果不是,则返回3.

  • checknumber函数用于判断数字是质数、阿姆斯特朗数还是完全数.然后它会返回:

  • 如果该数是素数,则为0.

  • 如果数字是完全数,则为1.

  • 如果号码是阿姆斯特朗,则为2.

  • 如果数是阿姆斯特朗和素数,则为3.

  • 4如果数字是阿姆斯特朗和阿姆斯特朗的完美.

  • 5.否则.

main函数中, 我做了一个无限循环,向用户询问他想要判断的号码,在判断之后,我询问用户是否想判断另一个号码.我还为checknumber函数设置了switch以打印输入的数字,例如:

用户输入7,输出为:

 This number is Armstrong & Prime.
 Want to check another number? (1) to continue; (0) to close.

问题是,当我使用这个数字(28116440335967)进行判断时,程序永远不会产生任何输出,我也不知道为什么.

推荐答案

您需要一种更高效的算法来判断素数和完全数:按照编码,您在prime()函数中迭代n / 2次,在perfect()函数中迭代n次.

由于28116440335967是一个质数,prime(x)需要很长的时间,perfect(x)甚至更长,这就解释了输出不足的原因:程序只是全速运行,但花费的时间太长了.

您可以通过只迭代到x的平方根来降低这两个函数的复杂性:

int prime(long long int n) {
    if (n < 2)
        return 0;
    if (n % 2 == 0)
        return n == 2;
    for (long long i = 3; i <= n / i; i += 2) {
        if (n % i == 0) {
            return 1;
        }
    }
    return 0;
}

int perfect(long long int n) {
    long long int i, q, np = 1;

    for (i = 2; i <= (q = n / i); i++) {
        if (n % i == 0) {
            np = np + i;
            if (q != i)
                np = np + q;
        }
    }
    if (np == n) {
        return 1;
    } else {
        return 2;
    }
}

另请注意这些备注:

  • prime()函数返回0是质数,而1是素数,这会让人感到困惑.

  • 如果数字分别不是primeArmstrongperfect,则prime()armstrong()perfect()返回0会直观得多,如果数字是1,则返回1.

  • 对返回值为CheckNumber()的组合使用二进制指示符将使代码更简单且更具可读性.

  • 建议对armstrong()函数使用整数运算,以避免函数log10pow出现精度问题.

以下是修改后的版本:

#include <stdio.h>

enum { PRIME = 1, ARMSTRONG = 2, PERFECT = 4 };

int checkNumber(long long int x);
int prime(long long int n);
int armstrong(long long int n);
int perfect(long long int n);

int main(void) {
    for (;;) {
        long long int n;

        printf("Enter a number to be checked: ");
        if (scanf("%lld", &n) != 1) {
            printf("\n");
            break;
        }
        switch (checkNumber(n)) {
        case PRIME:
            printf("This number is Prime\n");
            break;
        case PERFECT:
            printf("This number is Perfect\n");
            break;
        case ARMSTRONG:
            printf("This number is Armstrong\n");
            break;
        case ARMSTRONG + PRIME:
            printf("This number is Armstrong & Prime\n");
            break;
        case ARMSTRONG + PERFECT:
            printf("This number is Armstrong & Perfect.\n");
            break;
        default:
            printf("This number is otherwise.\n");
            break;
        }
    }
    return 0;
}

int prime(long long int n) {
    if (n < 2)
        return 0;
    if (n % 2 == 0)
        return n == 2;
    for (long long i = 3; i <= n / i; i += 2) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

int perfect(long long int n) {
    long long int i, q, np = 1;

    for (i = 2; i <= (q = n / i); i++) {
        if (n % i == 0) {
            np = np + i;
            if (q != i)
                np = np + q;
        }
    }
    return np == n;
}

int armstrong(long long int n) {
    long long int sum;
    long long int x;
    int nfi;

    if (n == 0)
        return 0;
    for (nfi = 0, x = n; x; x /= 10)
        nfi++;
    for (sum = 0, x = n; x; x /= 10) {
        long long int digit = x % 10;
        long long int val = digit;
        for (int i = 1; i < nfi; i++) {
            val *= digit;
        }
        sum += val;
    }
    return (n == sum);
}

int checkNumber(long long int n) {
    return prime(n) * PRIME | perfect(n) * PERFECT | armstrong(n) * ARMSTRONG;
}

C++相关问答推荐

如何在C中通过转换为char * 来访问float的字节表示?

char为16位且Short也为16位的c环境合法吗

C限制限定符是否可以通过指针传递?

%p与char* 等组合缺少的GCC Wform警告

位屏蔽对于无符号转换是强制的吗?

为什么在函数内部分配内存空间时需要添加符号?

为什么可以在typedef之前使用typedef d struct 体?

ESP32在vTaskDelay上崩溃

如何创建一个C程序来存储5种动物的名字,并在用户 Select 其中任何一种动物时打印内存地址?

在C++中通过空指针隐式访问常量变量的值

在Apple Silicon上编译x86的Fortran/C程序

使用TCL C API导航到列表中的元素

C I/O:在Windows控制台上处理键盘输入

在C++中允许使用字符作为宏参数

与外部SPI闪存通信时是否应禁用中断?

用C++初始化局部数组变量

C程序printf在getchar while循环后不工作

计算时出现奇怪的计算错误;N Select K;在C中

快速准确计算double的小数指数

设置具有非零终止字符串的大整数