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

Golang实现HackerRank Day8挑战:为何bufio.NewReader少输出一行?

bufio.NewReader与bufio.NewScanner在HackerRank上的输出差异原因

我在本地终端用bufio.NewReader实现HackerRank Day8通讯录查询挑战时输出正常,但在HackerRank平台上会少输出一行结果,切换为bufio.NewScanner后问题解决。


出错的代码

func main() {
    reader := bufio.NewReader(os.Stdin)

    // 读取条目数量
    line, _ := reader.ReadString('\n')
    num, _ := strconv.Atoi(strings.TrimSpace(line))

    // 创建通讯录Map
    phonebook := make(map[string]string)

    // 读取num行姓名和电话
    for i := 0; i < num; i++ {
        line, _ = reader.ReadString('\n')
        parts := strings.Fields(line)
        name := parts[0]
        number := parts[1]
        phonebook[name] = number
    }

    var results []string

    // 处理查询直到EOF
    for i := 0; i < num; i++ {
        qu, err := reader.ReadString('\n')
        if err != nil {
            break
        }

        qu = strings.TrimSpace(qu)
        if phone, found := phonebook[qu]; found {
            results = append(results, fmt.Sprintf("%s=%s", qu, phone))
        } else {
            results = append(results, "Not found")
        }
    }
}

正常运行的代码

func main() {
    scanner := bufio.NewScanner(os.Stdin)

    // 读取条目数量
    scanner.Scan()
    num, _ := strconv.Atoi(strings.TrimSpace(scanner.Text()))

    // 创建通讯录Map
    phonebook := make(map[string]string)

    // 读取num行姓名和电话
    for i := 0; i < num; i++ {
        scanner.Scan()
        parts := strings.Fields(scanner.Text())
        name := parts[0]
        number := parts[1]
        phonebook[name] = number
    }

    var results []string

    // 处理剩余所有输入作为查询
    for scanner.Scan() {
        qu := strings.TrimSpace(scanner.Text())
        if phone, found := phonebook[qu]; found {
            results = append(results, fmt.Sprintf("%s=%s", qu, phone))
        } else {
            results = append(results, "Not found")
        }
    }

    // 检查扫描错误
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "读取输入错误:", err)
    }

    // 一次性输出所有结果
    fmt.Println(strings.Join(results, "\n"))
}

示例输入输出

示例输入

3
sam 99912222
tom 11122222
harry 12299933
sam
edward
harry

(注:平台输入也可能存在无换行的情况,比如所有内容在同一行)

预期输出

sam=99912222
Not found
harry=12299933

使用bufio.NewReader的输出

sam=99912222
Not found

使用bufio.NewScanner的输出

sam=99912222
Not found
harry=12299933

差异原因分析

  1. 查询循环逻辑错误
    出错代码中处理查询的循环是for i := 0; i < num; i++,错误地假设查询数量等于通讯录条目数量num。但题目要求是处理所有后续输入直到EOF,而非固定num次查询,这个逻辑本身就不符合题目要求。

  2. EOF处理方式不同

    • bufio.NewReader.ReadString('\n')依赖换行符分割内容:如果输入的最后一行没有换行符,它会返回该行内容并附带io.EOF错误,出错代码遇到错误直接break循环,导致最后一个查询被丢弃。
    • bufio.NewScanner.Scan()会自动适配无换行的结尾:只要还有未读取的内容,即使没有换行符,Scan()也会返回true并读取内容,直到真正的EOF才停止,不会遗漏最后一条查询。
  3. 输入格式兼容性问题
    HackerRank平台的输入可能存在不规范的换行(比如所有内容在同一行),bufio.NewScanner默认的扫描行为(按行分割,同时处理空白字符)比ReadString('\n')更健壮,能适应不同的输入格式;而ReadString('\n')依赖明确的换行符,一旦输入未按预期换行就会读取错误内容,导致后续逻辑异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:47:09