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

Golang处理大数值时Scan-read运行时错误求助

问题解决:Codeforces 803B 大输入下的数组越界panic

错误根源

你遇到的panic: runtime error: index out of range本质是输入读取的房屋数houses与实际读取到的street数组长度不匹配。当处理大测试用例时,输入读取函数没有正确获取完整的数组元素,导致street长度远小于houses,后续循环访问street[i]时触发越界。

具体问题点

  1. 未处理扫描错误:readInt和readArray中没有检查scanner.Scan()的返回值。如果输入中断或格式错误,scanner.Text()会返回空字符串,解析出的数值或数组完全错误。
  2. 空格处理不当:用strings.Split(" ")分割数组行时,若存在多空格、行尾空格,会生成空字符串元素,导致数组长度异常。
  3. 忽略解析错误:strconv.Atoi的错误被直接忽略,若输入包含非数字字符,会导致数组元素值错误或长度不匹配。
  4. 缺失min函数:你的代码中调用了min但未定义,这会导致编译错误(可能你贴代码时遗漏,但必须补充)。

修复步骤

1. 完善输入读取函数

替换原有的readInt和readArray,增加错误处理并优化空格分割:

func readInt(scanner *bufio.Scanner) int {
    if !scanner.Scan() {
        if err := scanner.Err(); err != nil {
            panic(err)
        }
        panic("读取房屋数时遇到输入结束")
    }
    stringInt := scanner.Text()
    res, err := strconv.Atoi(strings.TrimSpace(stringInt))
    if err != nil {
        panic("无效的房屋数输入: " + stringInt)
    }
    return res
}

func readArray(scanner *bufio.Scanner) []int {
    if !scanner.Scan() {
        if err := scanner.Err(); err != nil {
            panic(err)
        }
        panic("读取数组时遇到输入结束")
    }
    // 用Fields自动忽略所有空白符(多空格、换行、制表符)
    listString := strings.Fields(scanner.Text())
    arr := make([]int, len(listString))
    for i := 0; i < len(listString); i++ {
        res, err := strconv.Atoi(listString[i])
        if err != nil {
            panic("无效的数组元素: " + listString[i])
        }
        arr[i] = res
    }
    return arr
}

2. 校验输入匹配

在主函数中添加校验,确保数组长度与房屋数一致:

func main() {
    scanner := makeScanner()
    houses := readInt(scanner)
    street := readArray(scanner)
    if len(street) != houses {
        panic("输入的数组长度与房屋数不匹配")
    }
    printArray(closestZero(houses, street))
}

3. 补充缺失的min函数

在代码中添加min函数:

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

4. 备选:改用bufio.Reader处理超大输入

如果测试用例的数组行超长(超过3MB),改用bufio.Reader按单词读取更可靠:

func main() {
    reader := bufio.NewReader(os.Stdin)
    housesStr, _ := reader.ReadString('\n')
    houses, err := strconv.Atoi(strings.TrimSpace(housesStr))
    if err != nil {
        panic("无效的房屋数输入")
    }
    street := make([]int, houses)
    for i := 0; i < houses; i++ {
        _, err := fmt.Fscan(reader, &street[i])
        if err != nil {
            panic("读取数组元素失败")
        }
    }
    printArray(closestZero(houses, street))
}

这种方式无需关心行的长度,直接按输入中的数字依次读取,彻底避免行分割问题。

验证修复

修复后,无论是小输入还是大输入,都会先确保street数组长度与houses严格一致,同时处理输入过程中的各种异常,彻底解决越界panic。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:27:07