【问题标题】:Recursive and no-recursive get different answer递归和非递归得到不同的答案
【发布时间】:2019-05-08 00:40:01
【问题描述】:

抱歉,我的母语不是英语。

作业是关于计算模数的。股息是如此之大(a^y,a 和 y 可能是 10^18),所以我应该使用公式:(m * n)%d=(m%d * n%d)%d 来完成它。

所以我的逻辑如下:

如果 y=0,则返回 1%d

如果 y=1,返回 a%d

如果 y 是偶数,则返回递归并让 m=n=a^(y/2)

如果 y 是奇数,则返回递归并令 m=x^(y-1) n=a

问题是:y是奇数,x有两种不同的解法:

  • 1:直接计算(a%d)

  • 2:使用递归,幂为1

您可以在下面看到我的代码。在~~ ~~中,如果填写“a%d”是正确的但“remain(1)”是错误的。

但只有方法1答案是正确的。

在同样使用方法1中也可以得到正确答案。我还是想知道为什么使用方法2是错误的? 那么如何使用方法2来解决这个问题呢?如果可以,我应该如何修改代码?我不能,为什么?

我已尝试使用 2 种不同的方法以任何递归方式打印子答案。我看到方法 2 虽然 y 是奇数,但它的子答案是错误的,它可能会返回一个负值。

这是我的代码如下:

#include <stdio.h>

long long int a,i,d;

int remain(long long int y){
  if(y==0) return 1%d;
  else if(y==1) return a%d;
  else if(y%2==0) {long long int temp=remain(y/2); return (temp*temp)%d;}
  else if(y%2==1) return ((remain(y-1))*(~~remain(1)~~))%d;
 }

int main(void){
  scanf("%lld %lld %lld",&a,&i,&d);
  printf("%lld\n",remain(i));
  return 0;
} 

如果输入16777215 16777215 23842982

方法1的答案是6647725(正确)。

方法 2 的答案是 12467225(错误)。

TA 和我不知道为什么方法 2 是错误的。我的助教建议我在这里问这个问题。非常感谢。

【问题讨论】:

  • 对于低数字是否有效?
  • if 包含return 时,不需要else,只会使代码混乱。
  • 我打错了。请将第 8 段和第 9 段中的“x”替换为“a”。
  • 您应该缩进您的代码,并在其中使用一些空格。关于如何做到这一点的一个很好的指南:kernel.org/doc/html/v4.10/process/coding-style.html
  • 请不要这样混淆你的代码。使用换行符、空格、空行和 cmets 使您的代码更具可读性。可读的代码更容易理解,更容易理解的代码会更容易维护。如果您想与他人合作,也非常欢迎良好的习惯。并且不要使用全局变量,如果您需要将值传递给函数,请将它们作为参数传递。

标签: c recursion


【解决方案1】:

remain() 必须定义为long long int。 你有它的方式,你在这里乘两个 ints 并观察一个整数溢出:

else if(y%2==1) return ((remain(y-1))*(remain(1)))%d;

我已经检查过:一旦我将定义固定为

long long int remain(long long int y)

我得到了预期的结果

顺便说一句。您可以在启用编译器警告的情况下看到这一点,因为printf() 会导致编译器警告(至少 gcc 会)

【讨论】:

【解决方案2】:

我猜你正在溢出你使用的类型。也许int64_t remain(int64_t y); 会起作用。

我将使用更广泛的类型并修复您的代码样式,以便您了解如何正确编码。我还将使用固定宽度的整数,这是你 99% 的时间应该使用的(除非有充分的理由不使用)。

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>


int64_t a, i, d;


int64_t remain(int64_t y)
{
        int64_t temp;

        if (!y)
                return 1 % d;
        if (y == 1)
                return a % d;
        if (!(y % 2)) {
                temp = remain(y / 2);
                return (temp * temp) % d;
        }
        return (remain(y - 1) * remain(1)) % d;
}


int main(void)
{

        scanf("%"SNCi64" %"SCNi64" %"SCNi64"", &a, &i, &d);
        printf("%"PRIi64"\n", remain(i));

        return 0;
}

我没有解决诸如使用全局变量之类的问题,但你应该这样做。

【讨论】:

    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2013-03-30
    • 1970-01-01
    • 2020-07-20
    相关资源
    最近更新 更多