You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia编写的sublime number检测代码对12的多数倍数报错求因

Sublime Number检测代码的BoundsError问题

问题背景

Sublime Number的定义需满足两个条件:

  • 其正约数(含自身)的个数是一个完美数;
  • 其正约数(含自身)的和是一个完美数。
    (完美数定义:除自身外的正约数之和等于自身)

12本身是Sublime Number,但我的代码对它的多数倍数会报BoundsError,仅36、72、144、288……这类倍数(第3、6、12、24个倍数及后续同序列倍数)能正常运行,其他倍数均报错,代码对其他数字运行正常,求分析原因。

代码实现

function sublime(n)
    ncheck = zeros(Int64, n)
    k = 1

    for k = 1:n
        if rem(n,k) == 0
            ncheck[k] = k
        else
            #do nothing
        end
    end
    ncheck = filter!(x -> x != 0, ncheck)

    divsum = sum(ncheck)
    sumcheck = zeros(Int64, divsum)
    for k = 1:(divsum-1)
        if rem(divsum, k) == 0
            sumcheck[k] = k
        else
            #do nothing
        end
    end
    sumcheck = filter!(x -> x != 0, sumcheck)

    divnum = size(ncheck,1)
    lcheck = zeros(Int64, divnum)
    for k = 1:(divnum-1)
        if rem(divnum, k) == 0
            lcheck[k] = k
        else
            #do nothing
        end
    end
    lcheck = filter!(x -> x != 0, lcheck)

    if sum(lcheck) == divnum & sum(sumcheck) == divsum
        println("y")
    else
        println("n")
    end
end

代码逻辑说明

  1. 创建长度为n的全零数组ncheck,遍历筛选出n的所有正约数并移除零元素;
  2. 计算约数和divsum,创建长度为divsum的数组sumcheck,筛选divsum的所有真约数;
  3. 计算约数个数divnum,创建长度为divnum的数组lcheck,筛选divnum的所有真约数;
  4. 判断lcheck的和是否等于divnum(即divnum是完美数)、sumcheck的和是否等于divsum(即divsum是完美数),以此判定n是否为Sublime Number。

错误信息

运行sublime(12)的错误

sublime(12)

ERROR: BoundsError: attempt to access 12-element Vector{Int64} at index [14]
Stacktrace:
 [1] setindex!
   @ .\array.jl:969 [inlined]
 [2] sublime(n::Int64)
   @ Main .\REPL[49]:19
 [3] top-level scope
   @ REPL[78]:1

运行sublime(24)的错误

sublime(24)

ERROR: BoundsError: attempt to access 24-element Vector{Int64} at index [30]
Stacktrace:
 [1] setindex!
   @ .\array.jl:969 [inlined]
 [2] sublime(n::Int64)
   @ Main .\REPL[49]:19
 [3] top-level scope
   @ REPL[80]:1

运行sublime(48)的错误

sublime(48)

ERROR: BoundsError: attempt to access 48-element Vector{Int64} at index [62]
Stacktrace:
 [1] setindex!
   @ .\array.jl:969 [inlined]
 [2] sublime(n::Int64)
   @ Main .\REPL[49]:19
 [3] top-level scope
   @ REPL[82]:1

错误原因分析

从错误信息能直接看出,问题出在尝试访问长度为n的数组时用了大于n的索引(比如sublime(12)中用索引14访问12元素数组),结合栈追踪定位到sumcheck[k] = k这一行。

核心问题:你提供的代码里sumcheck = zeros(Int64, divsum)的写法是正确的,但大概率是代码复制时的格式问题——你写的x ->是HTML转义字符,而非Julia原生的箭头->,这会导致filter!函数无法正确过滤ncheck数组,使得ncheck仍保留原长度n,后续即使divsum计算正确,也可能因解释器异常导致sumcheck数组被错误设置为长度n,最终触发索引越界。

另外还有两个可优化的点:

  1. Julia中逻辑与应该用&&而非&,&是按位与运算符,虽然这里结果可能一致,但不符合代码语义;
  2. 无需创建全零数组再过滤,直接用列表推导式收集约数更高效,能减少出错概率。

修正后的代码示例

# 生成所有正约数
function get_divisors(n)
    return [k for k in 1:n if rem(n, k) == 0]
end

# 判断是否为完美数
function is_perfect(m)
    if m <= 1
        return false
    end
    # 计算真约数和(不包含自身)
    proper_sum = sum(k for k in 1:m-1 if rem(m, k) == 0)
    return proper_sum == m
end

# 判断是否为Sublime Number
function sublime(n)
    divs = get_divisors(n)
    div_count = length(divs)
    div_sum = sum(divs)
    
    if is_perfect(div_count) && is_perfect(div_sum)
        println("y")
    else
        println("n")
    end
end

内容的提问来源于stack exchange,提问作者QuarkbällchenAddict

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:58:09