加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 除数之和(除了它本身)

发布时间:2020-12-16 09:59:54 所属栏目:百科 来源:网络整理
导读:编写一个从键盘读取整数的程序,并在输出中写入n的除数之和(除了它自身). 我创建了一个找到除数之和的方法.使用while语句我可以在EOF之前输入最多10个整数.在while语句中,我得到sum = sum_divisor的输出并打印出sum. 如果我输入0 0 0 4 5 6 12,则输出应为0 0
编写一个从键盘读取整数的程序,并在输出中写入n的除数之和(除了它自身).

我创建了一个找到除数之和的方法.使用while语句我可以在EOF之前输入最多10个整数.在while语句中,我得到sum = sum_divisor的输出并打印出sum.

如果我输入0 0 0 4 5 6 12,则输出应为0 0 0 3 1 6 16.
我得到的输出是0 0 0 3 4 10 26.我怎样才能使它不会将sum_divisor添加到前一个总和?

#include <stdio.h>

int sum_divisor(int x);

int main()
{
    int x;
    int sum;
    printf("Enter up to 10 positive integer ending with EOF:n");

    while((scanf("%d",&x)) != EOF){
        sum = sum_divisor(x);
        printf("%d ",sum);
    }
    return 0;
}

int sum_divisor(int x){

    int i;
    int sum;

    if(x<= 0){
        sum = 0;
    }
    else{
        for(i=1;i<x;++i)
            {
                if(x%i==0)
                    sum += i;
            }
    }
    return sum;
}

解决方法

您应该在函数中将sum初始化为零.否则,它将被设置为某个任意值,而else块将具有任意结果.

换句话说,改变:

int sum;

成:

int sum = 0;

当然,一旦你完成了这个,就没有必要为x小于1的情况明确地做任何事情.另外,初始if是多余的,因为当x小于1时,for body将不会执行,所以你可以逃脱:

int sumDivisors (int x) {
    int i,sum = 0;

    for (i = 1 ; i < x; i++) {
        if ((x % i) == 0) {
            sum += i;
        }
    }
    return sum;
}

顺便说一句,您实际看到的没有初始化的值正在积累:

0 ->  0
 0 ->  0
 0 ->  0
 3 ->  3
 1 ->  4
 6 -> 10
16 -> 26

这几乎可以肯定是因为对函数的每次调用都是为堆栈帧重用相同的内存,包括变量sum,所以sum只是每次添加(传入的参数大于1).

然而,这仅仅是实现的工件,它不是由标准保证的,它在C11中非常清楚地表明6.7.9初始化/ 10:

If an object that has automatic storage duration is not initialized explicitly,its value is indeterminate.

换句话说,不要依赖于此.

并且,除此之外,它是一个数学假设,如果数字n均匀地除以a,它也均匀地除以n / a.您可以利用这个优势来使代码更有效(但是,与所有优化一样,您应该测量,而不是猜测).

由于你将数字本身作为除数折扣,你必须将除数1视为一种特殊情况.您还必须将完美正方形视为一种特殊情况,这样您就不会将平方根添加两次.

以下代码将是一个很好的起点:

int sumDivisors (int x) {
    int i,sum;

    // Always return zero for -inf..1 inclusive.

    if (x < 2)
        return 0;

    // Otherwise,1 is factor,search for others
    //   up to but NOT including sqrt(x).
    for (i = 2,sum = 1 ; i * i < x; i++) {
        if ((x % i) == 0) {
            sum += i;
            sum += x / i;
        }
    }

    // Add in sqrt(x) ONCE for a perfect square.

    if (i * i == x)
        sum += i;

    return sum;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读