【问题标题】:Write a function gets number of squares and will return how many integer numbers are used as square编写一个函数获取平方数,并将返回多少个整数用作平方数
【发布时间】:2021-04-08 09:25:36
【问题描述】:

编写一个函数 getNumberOfSquares(int n) (C) / get_number_of_squares,它将返回有多少整数(从 1、2... 开始)提升到 2 的幂,然后相加后小于给定的某个数字参数。

例如 1:对于 n = 6,结果应该是 2,因为 1^2 + 2^2 = 1 + 4 = 5 和 5

对于上面的函数,我编写了一个程序,但是测试程序给出了一个错误,即当输入为 getNumberOfSquares(100000) 时,函数应该返回 66,但我的返回 403。

这是我的解决方案:

int getNumberOfSquares(int n){

    int sum=0;
    int limit=0;
    for (int i = 1; i < n && n>sum; ++i)
    {
        sum += i*i;
        ++limit;
        if(sum>=n){
            sum -= i*i;
            --limit;
        }
    }
    return limit;
}

【问题讨论】:

  • 尝试找出导致错误结果的最小可能输入。然后使用常见的调试技术(例如使用实际的调试器来单步调试代码)来尝试找出发生了什么。

标签: c algorithm math


【解决方案1】:

您想找到最大的i,例如sum &lt; n。所以这应该是打破循环的唯一条件。你甚至不需要检查i &lt; n

现在你的代码的问题是你修改sum 当它变得足够大以打破循环时,使它再次小于n。因此,如果sum &lt; n 是您唯一的条件,您将有一个无限循环。但是由于您有i &lt; n 条件,程序会不断将i*i 加减到sum 直到i &lt; n

如果n 足够小,则添加和减去i*i 不会改变sum,当循环中断时,您会得到结果。

但如果i 可以增长到足以使总和大于您可以拥有的最大int,则sum 会溢出并成为无意义的值。

解决办法是消除条件if(sum&gt;=n){}

删除条件将显示limit 类似于i,因此您甚至可以使用i 作为返回值。

请记住,您不需要条件i &lt; n,您的函数变为

int getNumberOfSquares(int n) {

    int i, sum = 0;

    for(i = 1; sum < n; ++i) {
        
        sum += i*i;
    }
    
    return i-2;
}

返回i-2,因为i 使sum &gt; n 已经比您想要返回的值大1,然后在检查sum &gt; n 之前,for 递增i

【讨论】:

    【解决方案2】:

    假设您的系统上的整数是 32 位,i*i 一旦达到 65536 的值就会溢出。这会导致不准确。

    但是它实际上不应该达到那个点,因为即使在sum 的值超过n 之后,您仍会继续检查i 的值。当你到达那个点时,你应该跳出循环。

    int getNumberOfSquares(int n){
    
        int sum=0;
        int limit=0;
        for (int i = 1; i < n; ++i)
        {
            if (sum + i*i >= n) {
                return limit;
            }
            sum += i*i;
            ++limit;
        }
        return limit;
    }
    

    【讨论】:

    • 谢谢。您能否详细说明或给我一些资料来解释这些溢出的东西?为什么 i*i 操作会溢出?
    • 32 位有符号整数可以容纳的最大数是 2147483647,即 2^31-1。当计算超过这个值时,正式地你有未定义的行为,但实际上这通常意味着值“环绕”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2015-03-04
    • 2022-11-15
    • 1970-01-01
    • 2011-08-25
    • 2013-09-22
    相关资源
    最近更新 更多