C ++程序未完全执行迭代

时间:2018-09-17 13:46:13

标签: c++

我编写的程序应该接受两个用户输入(一个是我们要检查它是否为k完美的数字,另一个为最大k值)。在1到输入的最大k值之间是k-hyperperfect,则输出应该是该k值。例如,如果输入整数为21,最大k值为100,则输出应为2。

我的程序给出正确的输出(第一个数字是输入整数,第二个数字是k-max值,第三个数字是输出值)...

  • 21(输入整数)100(k-max)-> 180
  • 301100-> 6
  • 12211188308281 100-> 0
  • -301 100-> 0
  • 21 -5-> 0

但是,它不能正确执行12211188308281和200(它给我0时应该给我180)。我已经通过一步一步的可视化程序运行我的代码,并且在else语句中的for循环中,当我= 496时,它似乎突然停止了执行。但是我不明白为什么,因为它可以在其他5次测试中正确执行。

#include <iostream>
using std::cout; using std::cin; using std::endl; using std::fixed;


int main () { 
    int number; 
    int kmax; 
    int sum = 0 ; 
    int hyper = 0; 

    std::cin >> number; 
    std::cin >> kmax; 

    if (number <= 6 or kmax < 1) {
        std::cout << "0" << "\n"; 
    } 
    else { 
        for (int i=1;i<=number;i++) { 
            if (number%i==0 and i != 1 and i != number){ 
                    sum+= i; 
                }
            }
        }

    for (int k=1; k <= kmax; k++) { 
        hyper = ((sum)*k) + 1;
        if (hyper == number) { 
            std::cout << k << endl; 
            break; 
        } 
        } 

}

3 个答案:

答案 0 :(得分:1)

您需要检查通过std::istream(如std::cin)读取的数字是否已成功读取。由于您输入的数字值太大而无法存储为整数,因此读取将失败。例如,您可以将代码更改为:

int main()
{
    int number;     
    std::cin >> number; 
    if ( !std::cin )
    {
        std::cout << "invalid value: " << number << "\n";
        return 1;
    }
    else
    {
        std::cout << "valid value: " << number << "\n";        
    }
    // calculate answer
    return 0;
}

如果您使用的是c ++ 11兼容的编译器,那么您的程序将显示"invalid value: 2147483647";如果您使用的是较旧的编译器,则您的程序将显示未定义的数字。

现在,您已经正确实现了读取值的功能,解决此问题的方法是使用更大的整数类型,例如int64_t,它可以保存您的数字。

答案 1 :(得分:1)

如上所述,您机器上的int类型不足以存储值12,211,188,308,281。

C ++标准仅强制要求它能够存储最多32,767的值,即使在(现在很常见)32位intlong int的情况下,限制也会是2,147,483,647。因此,您需要一个long long int或一个int64_t(如果在实现中存在)。

简单的支票

if (std::cin >> number >> kmax ) { // perform calculations...

会早点显示错误。

那只蜜蜂说,为了使发布的代码更有效率,还可以对发布的代码进行一些简单的更改。可以考虑给定数的除数的“对称性”来优化第一个循环:这意味着,如果n可被a整除,则b = n / a是一个整数,b也是n的除数。这样会将迭代次数限制为n的平方根,而不是n。

long long int number, 
              kmax, 
              sum = 0; 

 // ...

long long int temp = number,
              i = 2;
for (; i * i < number; i++) { 
    if (number % i == 0) {
        temp = number / i;
        sum += i + temp; 
    }
}
if (i * i == number) {
    sum += i;
}

可能有更好的算法,但是我不熟悉这些算法。

我认为第二个循环是不必要的。值k可以直接计算:

if ( (number - 1) % sum == 0) {
    std::cout << (number - 1) / sum << '\n';
}

答案 2 :(得分:0)

您正在将太长的值12211188308281分配给整数“ number”,该整数不能完全包含它,并且将其截断为596285753。您可以添加打印语句以进行打印。

std::cout<<number; 

,它将打印596285753。 根据建议,您应该使用long long int。同样,它取决于系统上运行的软件平台。