获取所有方式以两个整数的产品表示数字

Get all ways to express a number as a product of two integers

本文关键字:整数 两个 数字 表示 方式 获取      更新时间:2023-10-16

我最近一直在玩寻找数字的除数,并决定尝试制作一个程序,该程序打印了所有方式,以表达数字n作为两个整数的产品。我写了一本用于正数的工作,只考虑构成产品的正数。

#include <iostream>
#include <cmath>
int main()
{
    int n;
    std::cin >> n;
    int root = std::sqrt(n);
    for(int i = 1; i <= root; i++)
    {
        if(n % i != 0)
            continue;
        int j = n / i;  
        std::cout << i << ", " << j << std::endl;
    }
    return 0;
}

上面的代码只是找到N的所有分隔线,并将它们作为对打印。它运行良好,但我想尝试使它找到所有可能的方法来获得N,而不仅仅是有正数。

例如,如果我在上面的程序中输入10,则结果将为(1,10),(2,5);这些是正确的,但是还有其他方法可以乘以两个数字并获得10。它涉及负数:(-1,-10),(-2,-5)也是解决方案,因为当您将两个负数乘以两个负数时,你最终得到了一个积极的。

如果我希望该程序仅处理正n值但也可以找到负倍数,那么我只能打印出I和J的负版本,因为您只能通过乘以两个正或两个负面或两个负面的数字来获得正数在一起。

有效的

,但是现在我想将此代码用于负n值。例如,n = -10的预期输出将为:(-1,10),(1,-10),(2,-5),(-2,5);

问题是,上面的算法只能找到正数的正分离,因为它涉及平方根,这仅针对正数定义,循环以正面为正并以正面为正。

我注意到我只能计算n的绝对值的平方根,然后使循环从-root开始,并在根部端以越过n的负分隔线。不过,我必须确保跳过0,因为没有定义0的划分,这使其崩溃。我最终以这样的代码:

#include <iostream>
#include <cmath>
int main()
{
    int n;
    std::cin >> n;
    int root_n = std::sqrt(std::abs(n));
    for(int i = -root_n; i <= root_n; i++)
    {
        if(i == 0 || n % i != 0)
            continue;
        int j = n / i;  
        std::cout << i << ", " << j << std::endl;
    }
    return 0;
}

它适用于我想出的所有测试,但我不确定这是写它的最佳方法。我有什么可以改进的吗?

预先感谢!

编辑:按照Caleth的建议使用STD :: DIV尝试(也使用Resharper addon in vs in vs in vs in vs five of Recrateforce提出建议):

#include <iostream>
#include <cstdlib>
int main()
{
    int n;
    std::cin >> n;
    const int sqrt_n = std::sqrt(std::abs(n));
    for(auto i = -sqrt_n; i <= sqrt_n; i++)
    {
        if (i == 0)
            continue;
        const auto div_res = std::div(n, i);
        if (div_res.rem)
            continue;
        std::cout << i << ", " << div_res.quot << std::endl;
    }
    return 0;
}

,我可以只对其进行计算,然后计算商,而是对STD ::div进行一次调用,该::div返回一个结构,包含两个值。

一个主要的观察结果是,除符号外,一个数字的负分别和正分裂是相同的。如果您只查看正数并自己处理标志,则可以节省一半的时间。例如,

int main()
{
    int n;
    std::cin >> n;
    int root_n = std::sqrt(std::abs(n));
    for(int i = 1; i <= root_n; i++) \ don't loop over negative numbers now
    {
        if(n % i != 0) \ not necessary to check for 0 anymore
            continue;
        int j = n / i;  
        std::cout << i << ", " << j << "n";
        std::cout << -i << ", " << -j << "n";  \ corresponding negative
    }
    return 0;
}

您可能会注意到我删除了std::endl ---您实际上不需要经常冲洗流。按照所需的输出缓冲区更快。

如果您正在寻找其他修改程序的方法,则可以尝试找到质量分解,然后从中计算除数列表。对于大型复合输入,这将更快。但这也完全不同。