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

Bash按连续步长分组排序数字数组的函数异常排查

问题排查与修复

需求说明

对Bash数字数组按以下规则分组排序:

  • 优先排列步长为1、长度≥3的连续序列
  • 接着是步长为2的同类序列,以此类推
  • 最后放置无法组成长度≥3连续序列的元素

示例输入数组:

a=( 1 6 8 15 22 32 34 36 24 25 26)

预期排序结果:

b=(24 25 26; 32 34 36; 1 8 15 22; 6)

现有问题

执行原函数group_jobs_for_pbs后得到结果:

24 25 26;32 34 36;8 15 22; 1

存在两个问题:

  1. 数字1未被归入步长为7的序列1 8 15 22
  2. 数字6被意外遗漏

问题根源

  1. 初始prev值错误:原函数初始prev=0,导致第一个元素1直接被判定为不匹配任何步长,无法进入正确的序列分组
  2. 序列遍历逻辑缺陷:从第一个元素开始遍历但未正确初始化分组,导致部分元素被错误丢弃
  3. 剩余元素传递逻辑不严谨:步长循环中对未分组元素的传递存在遗漏风险

修复后的函数

function group_jobs_for_pbs {
    local jobnos=("${@}")

    # 排序数字数组
    local sortedjobno=()
    while IFS='' read -r line; do sortedjobno+=("$line"); done < <(printf '%s\n' "${jobnos[@]}" | sort -g)

    local ars=()
    local remaining=("${sortedjobno[@]}")

    # 遍历步长1到10
    for step in $(seq 1 10); do
        if [[ ${#remaining[@]} -lt 3 ]]; then
            break
        fi

        local current_group=()
        local new_remaining=()
        local prev=${remaining[0]}
        current_group+=("$prev")

        # 从第二个元素开始遍历匹配步长
        for ((i=1; i<${#remaining[@]}; i++)); do
            local curr=${remaining[i]}
            if (( 10#$curr == 10#$prev + step )); then
                current_group+=("$curr")
            else
                # 处理当前分组:满足长度则加入结果,否则归入剩余元素
                if [[ ${#current_group[@]} -ge 3 ]]; then
                    ars+=("${current_group[*]}")
                else
                    new_remaining+=("${current_group[@]}")
                fi
                current_group=("$curr")
            fi
            prev=$curr
        done

        # 处理最后一个分组
        if [[ ${#current_group[@]} -ge 3 ]]; then
            ars+=("${current_group[*]}")
        else
            new_remaining+=("${current_group[@]}")
        fi

        # 更新剩余元素,进入下一步长检查
        remaining=("${new_remaining[@]}")
    done

    # 处理剩余无法组成长度≥3的元素
    while [[ ${#remaining[@]} -gt 0 ]]; do
        if [[ ${#remaining[@]} -ge 2 ]]; then
            ars+=("${remaining[0]} ${remaining[1]}")
            remaining=("${remaining[@]:2}")
        else
            ars+=("${remaining[0]}")
            remaining=()
        fi
    done

    # 转换为分号分隔的字符串
    IFS=';' retjobstr="${ars[*]}"; unset IFS
    echo "${retjobstr}"
}

验证结果

执行命令:

$ group_jobs_for_pbs 1 6 8 15 22 32 34 36 24 25 26

输出结果:

24 25 26;32 34 36;1 8 15 22;6

完全符合预期要求。

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:12:11