【问题标题】:why < is much faster than !=?为什么 < 比 != 快得多?
【发布时间】:2014-07-16 11:03:02
【问题描述】:

问题:考虑以下算法来生成一个序列 数字。从整数 n 开始。如果 n 是偶数,除以 2。如果 n 是 奇数,乘以 3 并加 1。使用新值重复此过程 n,当 n = 1 时终止。输入将由一系列 整数对 i 和 j,每行一对整数。所有整数 将小于 1,000,000 且大于 0。 对于每一对 输入整数 i 和 j,以相同的顺序输出 i、j 出现在输入中,然后是整数的最大循环长度 在 i 和 j 之间,包括 i 和 j。这三个数字应该分开 由一个空格,所有三个数字在一行和一行 每行输入的输出。

样本输入:

1 10

样本输出:

1 10 20

所以我写了这个:

#include <stdio.h>
#include <string.h>

struct line{int in1;int in2;int result;};

int cycle(int in);

int main(int argc, char *argv[]) {
    int cycle(int in);
    char c;
    int firstIn=0;
    struct line l[500] ;
    int pointer=0;

    while(2<3){
        l[pointer].in1=0;
        l[pointer].in2=0;
        scanf("%u %u",&l[pointer].in1,&l[pointer].in2);
        if(l[pointer].in1<1||l[pointer].in2<1){
            break;
        }

        int maxCyc=0;
        int j,m;
        int min,max;
        if(l[pointer].in1>l[pointer].in2){
            max=l[pointer].in1;
            min=l[pointer].in2;
        }
        else{
            max=l[pointer].in2;
            min=l[pointer].in1;
        }
        for(j=min;j<=max;j++){

            m = cycle(j);
            if(m>maxCyc)
                maxCyc=m;
        }
        l[pointer].result=maxCyc;
        printf("%d %d %d\n",l[pointer].in1,l[pointer].in2,l[pointer].result);
        pointer++;
    }
}

int cycle(int in){
    int cyc = 1;
    while(in>1){
        if(in%2==0){
            cyc++;
            in=in/2;
        }
        else{
            cyc++;
            in=in*3+1;
        }
    }
    return cyc;
}

完全没问题,但是当您将循环方法中的while(in&gt;1) 更改为while(in!=1) 时,它会变得更慢。我的问题是为什么?!

while(in&gt;1) 的时间:0.683 秒

当它的 while(in!=1) :我等了超过 5 分钟没有 还没有发生:)

输入:1 1000000

没有无限循环之类的,因为in 根本不能低于 1(因为它必须已经是 1)。

最好的问候

【问题讨论】:

  • 你的意思是“why != is much more faster than ”在标题中?
  • 你为什么有while(2&lt;3)?如果你想要一个无限循环,只需执行例如while(1)。尽管编译器无论如何都会将您的表达式优化为1
  • 这与&lt;!= 的速度无关。全部取决于循环中的执行次数。
  • 如果您认为是运算符使您的代码变慢,请创建一个较小的示例来说明这一点,其中要比较的两个运算符的数量或运算符执行次数相同。
  • 是否存在in=in*3+1; 遇到整数溢出并导致in 变为负数的任何数字?那么运营商就会有所作为

标签: c performance operators collatz


【解决方案1】:

当您使用输入值113383 调用cycle 时,进程最终将n 设置为 827370449,而 3*827370449+1 为 2482111348,大于最大值signed int,解释为-1812855948。所以你的第一个负数应该没有负数。

如果此过程最终将n 设置为-2,则从那时起它将在-2 和-1 之间无限循环。可能还有其他我没有考虑过的循环。

如果您要使用 unsigned int,则有可能(我没有检查过)它最终也会溢出,这不会导致负值,但会导致 不正确 值,使您的结果无效。

无论您使用哪种整数表示,最好将n 与每个循环顶部的(maximum-1)/3 进行比较,其中maximum 是您的整数类型的最大可能正值,只是确保不会溢出。

【讨论】:

    【解决方案2】:

    正如你所说,这是一个简单的溢出问题,谢谢大家。

    最大 int 值为2,147,483,647; 所以当我将int cycle(int in) 更改为int cycle(long long int in) 时,我的问题就解决了。

    我还发现我对while(in&gt;1) 的第一个回答是错误的。

    当整数溢出时,值会低于0。这就是while(in!=1)是一个无限循环的原因。

    我真的很累,我没有自己弄清楚。对此感到抱歉:)

    【讨论】:

      猜你喜欢
      • 2014-04-21
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 2011-11-30
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多